Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Arm Statistical Profiling Extensions (SPE) support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * Copyright (c) 2017-2018, Arm Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include <byteswap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <endian.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <inttypes.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/log2.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/zalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <stdlib.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include "auxtrace.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include "color.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include "debug.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include "evlist.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include "evsel.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #include "machine.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #include "session.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #include "symbol.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #include "thread.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #include "thread-stack.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #include "tool.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #include "util/synthetic-events.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #include "arm-spe.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #include "arm-spe-decoder/arm-spe-decoder.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #include "arm-spe-decoder/arm-spe-pkt-decoder.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #define MAX_TIMESTAMP (~0ULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) struct arm_spe {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	struct auxtrace			auxtrace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	struct auxtrace_queues		queues;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	struct auxtrace_heap		heap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	struct itrace_synth_opts        synth_opts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	u32				auxtrace_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	struct perf_session		*session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	struct machine			*machine;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	u32				pmu_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	u8				timeless_decoding;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	u8				data_queued;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	u64				sample_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	u8				sample_flc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	u8				sample_llc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	u8				sample_tlb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	u8				sample_branch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	u8				sample_remote_access;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	u64				l1d_miss_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	u64				l1d_access_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	u64				llc_miss_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	u64				llc_access_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	u64				tlb_miss_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	u64				tlb_access_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	u64				branch_miss_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	u64				remote_access_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	u64				kernel_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	unsigned long			num_events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) struct arm_spe_queue {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	struct arm_spe			*spe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	unsigned int			queue_nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	struct auxtrace_buffer		*buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	struct auxtrace_buffer		*old_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	union perf_event		*event_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	bool				on_heap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	bool				done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	pid_t				pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	pid_t				tid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	int				cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	struct arm_spe_decoder		*decoder;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	u64				time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	u64				timestamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	struct thread			*thread;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) static void arm_spe_dump(struct arm_spe *spe __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 			 unsigned char *buf, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	struct arm_spe_pkt packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	size_t pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	int ret, pkt_len, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	char desc[ARM_SPE_PKT_DESC_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	const char *color = PERF_COLOR_BLUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	color_fprintf(stdout, color,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 		      ". ... ARM SPE data: size %zu bytes\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 		      len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	while (len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 		ret = arm_spe_get_packet(buf, len, &packet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 		if (ret > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 			pkt_len = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 			pkt_len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 		printf(".");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 		color_fprintf(stdout, color, "  %08x: ", pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 		for (i = 0; i < pkt_len; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 			color_fprintf(stdout, color, " %02x", buf[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 		for (; i < 16; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 			color_fprintf(stdout, color, "   ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 		if (ret > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 			ret = arm_spe_pkt_desc(&packet, desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 					       ARM_SPE_PKT_DESC_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 			if (ret > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 				color_fprintf(stdout, color, " %s\n", desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 			color_fprintf(stdout, color, " Bad packet!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 		pos += pkt_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 		buf += pkt_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 		len -= pkt_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) static void arm_spe_dump_event(struct arm_spe *spe, unsigned char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 			       size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	printf(".\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	arm_spe_dump(spe, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) static int arm_spe_get_trace(struct arm_spe_buffer *b, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	struct arm_spe_queue *speq = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	struct auxtrace_buffer *buffer = speq->buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	struct auxtrace_buffer *old_buffer = speq->old_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	struct auxtrace_queue *queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	queue = &speq->spe->queues.queue_array[speq->queue_nr];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	buffer = auxtrace_buffer__next(queue, buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	/* If no more data, drop the previous auxtrace_buffer and return */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	if (!buffer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 		if (old_buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 			auxtrace_buffer__drop_data(old_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 		b->len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	speq->buffer = buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	/* If the aux_buffer doesn't have data associated, try to load it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	if (!buffer->data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 		/* get the file desc associated with the perf data file */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 		int fd = perf_data__fd(speq->spe->session->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 		buffer->data = auxtrace_buffer__get_data(buffer, fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 		if (!buffer->data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	b->len = buffer->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	b->buf = buffer->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	if (b->len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 		if (old_buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 			auxtrace_buffer__drop_data(old_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 		speq->old_buffer = buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 		auxtrace_buffer__drop_data(buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 		return arm_spe_get_trace(b, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) static struct arm_spe_queue *arm_spe__alloc_queue(struct arm_spe *spe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 		unsigned int queue_nr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	struct arm_spe_params params = { .get_trace = 0, };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	struct arm_spe_queue *speq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	speq = zalloc(sizeof(*speq));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	if (!speq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	speq->event_buf = malloc(PERF_SAMPLE_MAX_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	if (!speq->event_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 		goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	speq->spe = spe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	speq->queue_nr = queue_nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	speq->pid = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	speq->tid = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	speq->cpu = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	/* params set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	params.get_trace = arm_spe_get_trace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	params.data = speq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	/* create new decoder */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	speq->decoder = arm_spe_decoder_new(&params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	if (!speq->decoder)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 		goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	return speq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	zfree(&speq->event_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	free(speq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) static inline u8 arm_spe_cpumode(struct arm_spe *spe, u64 ip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	return ip >= spe->kernel_start ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 		PERF_RECORD_MISC_KERNEL :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 		PERF_RECORD_MISC_USER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) static void arm_spe_prep_sample(struct arm_spe *spe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 				struct arm_spe_queue *speq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 				union perf_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 				struct perf_sample *sample)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	struct arm_spe_record *record = &speq->decoder->record;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	if (!spe->timeless_decoding)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 		sample->time = speq->timestamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	sample->ip = record->from_ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	sample->cpumode = arm_spe_cpumode(spe, sample->ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	sample->pid = speq->pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	sample->tid = speq->tid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	sample->addr = record->to_ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	sample->period = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	sample->cpu = speq->cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	event->sample.header.type = PERF_RECORD_SAMPLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	event->sample.header.misc = sample->cpumode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	event->sample.header.size = sizeof(struct perf_event_header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) static int arm_spe__inject_event(union perf_event *event, struct perf_sample *sample, u64 type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	event->header.size = perf_event__sample_event_size(sample, type, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	return perf_event__synthesize_sample(event, type, 0, sample);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) static inline int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) arm_spe_deliver_synth_event(struct arm_spe *spe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 			    struct arm_spe_queue *speq __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 			    union perf_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 			    struct perf_sample *sample)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	if (spe->synth_opts.inject) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 		ret = arm_spe__inject_event(event, sample, spe->sample_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	ret = perf_session__deliver_synth_event(spe->session, event, sample);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 		pr_err("ARM SPE: failed to deliver event, error %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) arm_spe_synth_spe_events_sample(struct arm_spe_queue *speq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 				u64 spe_events_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	struct arm_spe *spe = speq->spe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	union perf_event *event = speq->event_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	struct perf_sample sample = { .ip = 0, };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	arm_spe_prep_sample(spe, speq, event, &sample);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	sample.id = spe_events_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	sample.stream_id = spe_events_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	return arm_spe_deliver_synth_event(spe, speq, event, &sample);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) static int arm_spe_sample(struct arm_spe_queue *speq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	const struct arm_spe_record *record = &speq->decoder->record;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	struct arm_spe *spe = speq->spe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	if (spe->sample_flc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 		if (record->type & ARM_SPE_L1D_MISS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 			err = arm_spe_synth_spe_events_sample(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 					speq, spe->l1d_miss_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 			if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 				return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 		if (record->type & ARM_SPE_L1D_ACCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 			err = arm_spe_synth_spe_events_sample(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 					speq, spe->l1d_access_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 			if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 				return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	if (spe->sample_llc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 		if (record->type & ARM_SPE_LLC_MISS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 			err = arm_spe_synth_spe_events_sample(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 					speq, spe->llc_miss_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 			if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 				return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 		if (record->type & ARM_SPE_LLC_ACCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 			err = arm_spe_synth_spe_events_sample(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 					speq, spe->llc_access_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 			if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 				return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	if (spe->sample_tlb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 		if (record->type & ARM_SPE_TLB_MISS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 			err = arm_spe_synth_spe_events_sample(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 					speq, spe->tlb_miss_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 			if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 				return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 		if (record->type & ARM_SPE_TLB_ACCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 			err = arm_spe_synth_spe_events_sample(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 					speq, spe->tlb_access_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 			if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 				return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 	if (spe->sample_branch && (record->type & ARM_SPE_BRANCH_MISS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 		err = arm_spe_synth_spe_events_sample(speq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 						      spe->branch_miss_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 	if (spe->sample_remote_access &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	    (record->type & ARM_SPE_REMOTE_ACCESS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 		err = arm_spe_synth_spe_events_sample(speq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 						      spe->remote_access_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) static int arm_spe_run_decoder(struct arm_spe_queue *speq, u64 *timestamp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	struct arm_spe *spe = speq->spe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	if (!spe->kernel_start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 		spe->kernel_start = machine__kernel_start(spe->machine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 		ret = arm_spe_decode(speq->decoder);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 		if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 			pr_debug("No data or all data has been processed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 			return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 		 * Error is detected when decode SPE trace data, continue to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 		 * the next trace data and find out more records.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 		ret = arm_spe_sample(speq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 		if (!spe->timeless_decoding && speq->timestamp >= *timestamp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 			*timestamp = speq->timestamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) static int arm_spe__setup_queue(struct arm_spe *spe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 			       struct auxtrace_queue *queue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 			       unsigned int queue_nr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 	struct arm_spe_queue *speq = queue->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 	struct arm_spe_record *record;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 	if (list_empty(&queue->head) || speq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 	speq = arm_spe__alloc_queue(spe, queue_nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 	if (!speq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 	queue->priv = speq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 	if (queue->cpu != -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 		speq->cpu = queue->cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 	if (!speq->on_heap) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 		int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 		if (spe->timeless_decoding)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) retry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 		ret = arm_spe_decode(speq->decoder);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 		if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 			goto retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 		record = &speq->decoder->record;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 		speq->timestamp = record->timestamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 		ret = auxtrace_heap__add(&spe->heap, queue_nr, speq->timestamp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 		speq->on_heap = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) static int arm_spe__setup_queues(struct arm_spe *spe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 	for (i = 0; i < spe->queues.nr_queues; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 		ret = arm_spe__setup_queue(spe, &spe->queues.queue_array[i], i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) static int arm_spe__update_queues(struct arm_spe *spe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 	if (spe->queues.new_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 		spe->queues.new_data = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 		return arm_spe__setup_queues(spe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) static bool arm_spe__is_timeless_decoding(struct arm_spe *spe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 	struct evsel *evsel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 	struct evlist *evlist = spe->session->evlist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 	bool timeless_decoding = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 	 * Circle through the list of event and complain if we find one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 	 * with the time bit set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 	evlist__for_each_entry(evlist, evsel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 		if ((evsel->core.attr.sample_type & PERF_SAMPLE_TIME))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 			timeless_decoding = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 	return timeless_decoding;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) static void arm_spe_set_pid_tid_cpu(struct arm_spe *spe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 				    struct auxtrace_queue *queue)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 	struct arm_spe_queue *speq = queue->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 	pid_t tid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 	tid = machine__get_current_tid(spe->machine, speq->cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 	if (tid != -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 		speq->tid = tid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 		thread__zput(speq->thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 		speq->tid = queue->tid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 	if ((!speq->thread) && (speq->tid != -1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 		speq->thread = machine__find_thread(spe->machine, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 						    speq->tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 	if (speq->thread) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 		speq->pid = speq->thread->pid_;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 		if (queue->cpu == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 			speq->cpu = speq->thread->cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) static int arm_spe_process_queues(struct arm_spe *spe, u64 timestamp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 	unsigned int queue_nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 	u64 ts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 	while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 		struct auxtrace_queue *queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 		struct arm_spe_queue *speq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 		if (!spe->heap.heap_cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 		if (spe->heap.heap_array[0].ordinal >= timestamp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 		queue_nr = spe->heap.heap_array[0].queue_nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 		queue = &spe->queues.queue_array[queue_nr];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 		speq = queue->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 		auxtrace_heap__pop(&spe->heap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 		if (spe->heap.heap_cnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 			ts = spe->heap.heap_array[0].ordinal + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 			if (ts > timestamp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 				ts = timestamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 			ts = timestamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 		arm_spe_set_pid_tid_cpu(spe, queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 		ret = arm_spe_run_decoder(speq, &ts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 			auxtrace_heap__add(&spe->heap, queue_nr, ts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 		if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 			ret = auxtrace_heap__add(&spe->heap, queue_nr, ts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 			if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 				return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 			speq->on_heap = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) static int arm_spe_process_timeless_queues(struct arm_spe *spe, pid_t tid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 					    u64 time_)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 	struct auxtrace_queues *queues = &spe->queues;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 	u64 ts = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 	for (i = 0; i < queues->nr_queues; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 		struct auxtrace_queue *queue = &spe->queues.queue_array[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 		struct arm_spe_queue *speq = queue->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 		if (speq && (tid == -1 || speq->tid == tid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 			speq->time = time_;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 			arm_spe_set_pid_tid_cpu(spe, queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 			arm_spe_run_decoder(speq, &ts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) static int arm_spe_process_event(struct perf_session *session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 				 union perf_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 				 struct perf_sample *sample,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 				 struct perf_tool *tool)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 	int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 	u64 timestamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 	struct arm_spe *spe = container_of(session->auxtrace,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 			struct arm_spe, auxtrace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 	if (dump_trace)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 	if (!tool->ordered_events) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 		pr_err("SPE trace requires ordered events\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 	if (sample->time && (sample->time != (u64) -1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 		timestamp = sample->time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 		timestamp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 	if (timestamp || spe->timeless_decoding) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 		err = arm_spe__update_queues(spe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 	if (spe->timeless_decoding) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 		if (event->header.type == PERF_RECORD_EXIT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 			err = arm_spe_process_timeless_queues(spe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 					event->fork.tid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 					sample->time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 	} else if (timestamp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 		if (event->header.type == PERF_RECORD_EXIT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 			err = arm_spe_process_queues(spe, timestamp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 			if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 				return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) static int arm_spe_process_auxtrace_event(struct perf_session *session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 					  union perf_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 					  struct perf_tool *tool __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 	struct arm_spe *spe = container_of(session->auxtrace, struct arm_spe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 					     auxtrace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 	if (!spe->data_queued) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 		struct auxtrace_buffer *buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 		off_t data_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 		int fd = perf_data__fd(session->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 		int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 		if (perf_data__is_pipe(session->data)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 			data_offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 			data_offset = lseek(fd, 0, SEEK_CUR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 			if (data_offset == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 				return -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 		err = auxtrace_queues__add_event(&spe->queues, session, event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 				data_offset, &buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 		/* Dump here now we have copied a piped trace out of the pipe */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 		if (dump_trace) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 			if (auxtrace_buffer__get_data(buffer, fd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 				arm_spe_dump_event(spe, buffer->data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 						buffer->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 				auxtrace_buffer__put_data(buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) static int arm_spe_flush(struct perf_session *session __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 			 struct perf_tool *tool __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 	struct arm_spe *spe = container_of(session->auxtrace, struct arm_spe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 			auxtrace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 	if (dump_trace)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 	if (!tool->ordered_events)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) 	ret = arm_spe__update_queues(spe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 	if (spe->timeless_decoding)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 		return arm_spe_process_timeless_queues(spe, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) 				MAX_TIMESTAMP - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 	return arm_spe_process_queues(spe, MAX_TIMESTAMP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) static void arm_spe_free_queue(void *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 	struct arm_spe_queue *speq = priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 	if (!speq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 	thread__zput(speq->thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 	arm_spe_decoder_free(speq->decoder);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) 	zfree(&speq->event_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) 	free(speq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) static void arm_spe_free_events(struct perf_session *session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 	struct arm_spe *spe = container_of(session->auxtrace, struct arm_spe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 					     auxtrace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 	struct auxtrace_queues *queues = &spe->queues;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) 	for (i = 0; i < queues->nr_queues; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) 		arm_spe_free_queue(queues->queue_array[i].priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) 		queues->queue_array[i].priv = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) 	auxtrace_queues__free(queues);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) static void arm_spe_free(struct perf_session *session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) 	struct arm_spe *spe = container_of(session->auxtrace, struct arm_spe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) 					     auxtrace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) 	auxtrace_heap__free(&spe->heap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) 	arm_spe_free_events(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) 	session->auxtrace = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) 	free(spe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) static bool arm_spe_evsel_is_auxtrace(struct perf_session *session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) 				      struct evsel *evsel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) 	struct arm_spe *spe = container_of(session->auxtrace, struct arm_spe, auxtrace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) 	return evsel->core.attr.type == spe->pmu_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) static const char * const arm_spe_info_fmts[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) 	[ARM_SPE_PMU_TYPE]		= "  PMU Type           %"PRId64"\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) static void arm_spe_print_info(__u64 *arr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) 	if (!dump_trace)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) 	fprintf(stdout, arm_spe_info_fmts[ARM_SPE_PMU_TYPE], arr[ARM_SPE_PMU_TYPE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) struct arm_spe_synth {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) 	struct perf_tool dummy_tool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) 	struct perf_session *session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) static int arm_spe_event_synth(struct perf_tool *tool,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) 			       union perf_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) 			       struct perf_sample *sample __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) 			       struct machine *machine __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) 	struct arm_spe_synth *arm_spe_synth =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) 		      container_of(tool, struct arm_spe_synth, dummy_tool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) 	return perf_session__deliver_synth_event(arm_spe_synth->session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) 						 event, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) static int arm_spe_synth_event(struct perf_session *session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) 			       struct perf_event_attr *attr, u64 id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) 	struct arm_spe_synth arm_spe_synth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) 	memset(&arm_spe_synth, 0, sizeof(struct arm_spe_synth));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) 	arm_spe_synth.session = session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) 	return perf_event__synthesize_attr(&arm_spe_synth.dummy_tool, attr, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) 					   &id, arm_spe_event_synth);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) static void arm_spe_set_event_name(struct evlist *evlist, u64 id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) 				    const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) 	struct evsel *evsel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) 	evlist__for_each_entry(evlist, evsel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) 		if (evsel->core.id && evsel->core.id[0] == id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) 			if (evsel->name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) 				zfree(&evsel->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) 			evsel->name = strdup(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) arm_spe_synth_events(struct arm_spe *spe, struct perf_session *session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) 	struct evlist *evlist = session->evlist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) 	struct evsel *evsel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) 	struct perf_event_attr attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) 	bool found = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) 	u64 id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) 	evlist__for_each_entry(evlist, evsel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) 		if (evsel->core.attr.type == spe->pmu_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) 			found = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) 	if (!found) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) 		pr_debug("No selected events with SPE trace data\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) 	memset(&attr, 0, sizeof(struct perf_event_attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) 	attr.size = sizeof(struct perf_event_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) 	attr.type = PERF_TYPE_HARDWARE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) 	attr.sample_type = evsel->core.attr.sample_type & PERF_SAMPLE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) 	attr.sample_type |= PERF_SAMPLE_IP | PERF_SAMPLE_TID |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) 		PERF_SAMPLE_PERIOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) 	if (spe->timeless_decoding)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) 		attr.sample_type &= ~(u64)PERF_SAMPLE_TIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) 		attr.sample_type |= PERF_SAMPLE_TIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) 	spe->sample_type = attr.sample_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) 	attr.exclude_user = evsel->core.attr.exclude_user;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) 	attr.exclude_kernel = evsel->core.attr.exclude_kernel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) 	attr.exclude_hv = evsel->core.attr.exclude_hv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) 	attr.exclude_host = evsel->core.attr.exclude_host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) 	attr.exclude_guest = evsel->core.attr.exclude_guest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) 	attr.sample_id_all = evsel->core.attr.sample_id_all;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) 	attr.read_format = evsel->core.attr.read_format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) 	/* create new id val to be a fixed offset from evsel id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) 	id = evsel->core.id[0] + 1000000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) 	if (!id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) 		id = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) 	if (spe->synth_opts.flc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) 		spe->sample_flc = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) 		/* Level 1 data cache miss */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) 		err = arm_spe_synth_event(session, &attr, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) 		spe->l1d_miss_id = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) 		arm_spe_set_event_name(evlist, id, "l1d-miss");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) 		id += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) 		/* Level 1 data cache access */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) 		err = arm_spe_synth_event(session, &attr, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) 		spe->l1d_access_id = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) 		arm_spe_set_event_name(evlist, id, "l1d-access");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) 		id += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) 	if (spe->synth_opts.llc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) 		spe->sample_llc = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) 		/* Last level cache miss */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) 		err = arm_spe_synth_event(session, &attr, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) 		spe->llc_miss_id = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) 		arm_spe_set_event_name(evlist, id, "llc-miss");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) 		id += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) 		/* Last level cache access */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) 		err = arm_spe_synth_event(session, &attr, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) 		spe->llc_access_id = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) 		arm_spe_set_event_name(evlist, id, "llc-access");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) 		id += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) 	if (spe->synth_opts.tlb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) 		spe->sample_tlb = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) 		/* TLB miss */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) 		err = arm_spe_synth_event(session, &attr, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) 		spe->tlb_miss_id = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) 		arm_spe_set_event_name(evlist, id, "tlb-miss");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) 		id += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) 		/* TLB access */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) 		err = arm_spe_synth_event(session, &attr, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) 		spe->tlb_access_id = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) 		arm_spe_set_event_name(evlist, id, "tlb-access");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) 		id += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) 	if (spe->synth_opts.branches) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) 		spe->sample_branch = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) 		/* Branch miss */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) 		err = arm_spe_synth_event(session, &attr, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) 		spe->branch_miss_id = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) 		arm_spe_set_event_name(evlist, id, "branch-miss");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) 		id += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) 	if (spe->synth_opts.remote_access) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) 		spe->sample_remote_access = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) 		/* Remote access */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) 		err = arm_spe_synth_event(session, &attr, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) 		spe->remote_access_id = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) 		arm_spe_set_event_name(evlist, id, "remote-access");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) 		id += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) int arm_spe_process_auxtrace_info(union perf_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) 				  struct perf_session *session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) 	struct perf_record_auxtrace_info *auxtrace_info = &event->auxtrace_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) 	size_t min_sz = sizeof(u64) * ARM_SPE_AUXTRACE_PRIV_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) 	struct arm_spe *spe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) 	if (auxtrace_info->header.size < sizeof(struct perf_record_auxtrace_info) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) 					min_sz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) 	spe = zalloc(sizeof(struct arm_spe));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) 	if (!spe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) 	err = auxtrace_queues__init(&spe->queues);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) 		goto err_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) 	spe->session = session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) 	spe->machine = &session->machines.host; /* No kvm support */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) 	spe->auxtrace_type = auxtrace_info->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) 	spe->pmu_type = auxtrace_info->priv[ARM_SPE_PMU_TYPE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) 	spe->timeless_decoding = arm_spe__is_timeless_decoding(spe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) 	spe->auxtrace.process_event = arm_spe_process_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) 	spe->auxtrace.process_auxtrace_event = arm_spe_process_auxtrace_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) 	spe->auxtrace.flush_events = arm_spe_flush;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) 	spe->auxtrace.free_events = arm_spe_free_events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) 	spe->auxtrace.free = arm_spe_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) 	spe->auxtrace.evsel_is_auxtrace = arm_spe_evsel_is_auxtrace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) 	session->auxtrace = &spe->auxtrace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) 	arm_spe_print_info(&auxtrace_info->priv[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) 	if (dump_trace)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) 	if (session->itrace_synth_opts && session->itrace_synth_opts->set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) 		spe->synth_opts = *session->itrace_synth_opts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) 		itrace_synth_opts__set_default(&spe->synth_opts, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) 	err = arm_spe_synth_events(spe, session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) 		goto err_free_queues;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) 	err = auxtrace_queues__process_index(&spe->queues, session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) 		goto err_free_queues;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) 	if (spe->queues.populated)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) 		spe->data_queued = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) err_free_queues:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) 	auxtrace_queues__free(&spe->queues);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) 	session->auxtrace = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) err_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) 	free(spe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) }