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) #include <errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) #include <inttypes.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) #include <stdlib.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include <unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <stdio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <sys/param.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <perf/cpumap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <perf/evlist.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <perf/mmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include "debug.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include "dso.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include "env.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include "parse-events.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include "trace-event.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include "evlist.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include "evsel.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include "thread_map.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include "machine.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #include "map.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #include "symbol.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #include "event.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #include "record.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #include "util/mmap.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #include "util/synthetic-events.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #include "thread.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #include "tests.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #include <linux/ctype.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #define BUFSZ	1024
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) #define READLEN	128
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) struct state {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	u64 done[1024];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	size_t done_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) static unsigned int hex(char c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	if (c >= '0' && c <= '9')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 		return c - '0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	if (c >= 'a' && c <= 'f')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 		return c - 'a' + 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	return c - 'A' + 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) static size_t read_objdump_chunk(const char **line, unsigned char **buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 				 size_t *buf_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	size_t bytes_read = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	unsigned char *chunk_start = *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	/* Read bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	while (*buf_len > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 		char c1, c2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 		/* Get 2 hex digits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 		c1 = *(*line)++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 		if (!isxdigit(c1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 		c2 = *(*line)++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 		if (!isxdigit(c2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 		/* Store byte and advance buf */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 		**buf = (hex(c1) << 4) | hex(c2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 		(*buf)++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 		(*buf_len)--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 		bytes_read++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 		/* End of chunk? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 		if (isspace(**line))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	 * objdump will display raw insn as LE if code endian
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	 * is LE and bytes_per_chunk > 1. In that case reverse
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	 * the chunk we just read.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	 * see disassemble_bytes() at binutils/objdump.c for details
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	 * how objdump chooses display endian)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	if (bytes_read > 1 && !bigendian()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 		unsigned char *chunk_end = chunk_start + bytes_read - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 		unsigned char tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 		while (chunk_start < chunk_end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 			tmp = *chunk_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 			*chunk_start = *chunk_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 			*chunk_end = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 			chunk_start++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 			chunk_end--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	return bytes_read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) static size_t read_objdump_line(const char *line, unsigned char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 				size_t buf_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	const char *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	size_t ret, bytes_read = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	/* Skip to a colon */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	p = strchr(line, ':');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	/* Skip initial spaces */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	while (*p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 		if (!isspace(*p))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 		p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 		ret = read_objdump_chunk(&p, &buf, &buf_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 		bytes_read += ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 		p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	} while (ret > 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	/* return number of successfully read bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	return bytes_read;
^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 read_objdump_output(FILE *f, void *buf, size_t *len, u64 start_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	char *line = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	size_t line_len, off_last = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	ssize_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	u64 addr, last_addr = start_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	while (off_last < *len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 		size_t off, read_bytes, written_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 		unsigned char tmp[BUFSZ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 		ret = getline(&line, &line_len, f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 		if (feof(f))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 			pr_debug("getline failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 			err = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 		/* read objdump data into temporary buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 		read_bytes = read_objdump_line(line, tmp, sizeof(tmp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 		if (!read_bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 		if (sscanf(line, "%"PRIx64, &addr) != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 		if (addr < last_addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 			pr_debug("addr going backwards, read beyond section?\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 		last_addr = addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 		/* copy it from temporary buffer to 'buf' according
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 		 * to address on current objdump line */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 		off = addr - start_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 		if (off >= *len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 		written_bytes = MIN(read_bytes, *len - off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 		memcpy(buf + off, tmp, written_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 		off_last = off + written_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	/* len returns number of bytes that could not be read */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	*len -= off_last;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	free(line);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) static int read_via_objdump(const char *filename, u64 addr, void *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 			    size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	char cmd[PATH_MAX * 2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	const char *fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	FILE *f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	fmt = "%s -z -d --start-address=0x%"PRIx64" --stop-address=0x%"PRIx64" %s";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	ret = snprintf(cmd, sizeof(cmd), fmt, "objdump", addr, addr + len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 		       filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	if (ret <= 0 || (size_t)ret >= sizeof(cmd))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	pr_debug("Objdump command is: %s\n", cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	/* Ignore objdump errors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	strcat(cmd, " 2>/dev/null");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	f = popen(cmd, "r");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	if (!f) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 		pr_debug("popen failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	ret = read_objdump_output(f, buf, &len, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	if (len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 		pr_debug("objdump read too few bytes: %zd\n", len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 		if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 			ret = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	pclose(f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) static void dump_buf(unsigned char *buf, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	size_t i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	for (i = 0; i < len; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 		pr_debug("0x%02x ", buf[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 		if (i % 16 == 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 			pr_debug("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	pr_debug("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) static int read_object_code(u64 addr, size_t len, u8 cpumode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 			    struct thread *thread, struct state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	struct addr_location al;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	unsigned char buf1[BUFSZ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	unsigned char buf2[BUFSZ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	size_t ret_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	u64 objdump_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	const char *objdump_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	char decomp_name[KMOD_DECOMP_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	bool decomp = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	pr_debug("Reading object code for memory address: %#"PRIx64"\n", addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	if (!thread__find_map(thread, cpumode, addr, &al) || !al.map->dso) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 		if (cpumode == PERF_RECORD_MISC_HYPERVISOR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 			pr_debug("Hypervisor address can not be resolved - skipping\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 		pr_debug("thread__find_map failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	pr_debug("File is: %s\n", al.map->dso->long_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	if (al.map->dso->symtab_type == DSO_BINARY_TYPE__KALLSYMS &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	    !dso__is_kcore(al.map->dso)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 		pr_debug("Unexpected kernel address - skipping\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	pr_debug("On file address is: %#"PRIx64"\n", al.addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	if (len > BUFSZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 		len = BUFSZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	/* Do not go off the map */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	if (addr + len > al.map->end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 		len = al.map->end - addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	/* Read the object code using perf */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	ret_len = dso__data_read_offset(al.map->dso, thread->maps->machine,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 					al.addr, buf1, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	if (ret_len != len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 		pr_debug("dso__data_read_offset failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	 * Converting addresses for use by objdump requires more information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	 * map__load() does that.  See map__rip_2objdump() for details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	if (map__load(al.map))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	/* objdump struggles with kcore - try each map only once */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	if (dso__is_kcore(al.map->dso)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 		size_t d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 		for (d = 0; d < state->done_cnt; d++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 			if (state->done[d] == al.map->start) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 				pr_debug("kcore map tested already");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 				pr_debug(" - skipping\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 				return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 		if (state->done_cnt >= ARRAY_SIZE(state->done)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 			pr_debug("Too many kcore maps - skipping\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 		state->done[state->done_cnt++] = al.map->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	objdump_name = al.map->dso->long_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	if (dso__needs_decompress(al.map->dso)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 		if (dso__decompress_kmodule_path(al.map->dso, objdump_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 						 decomp_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 						 sizeof(decomp_name)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 			pr_debug("decompression failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 			return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 		decomp = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 		objdump_name = decomp_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	/* Read the object code using objdump */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	objdump_addr = map__rip_2objdump(al.map, al.addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	ret = read_via_objdump(objdump_name, objdump_addr, buf2, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	if (decomp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 		unlink(objdump_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	if (ret > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 		 * The kernel maps are inaccurate - assume objdump is right in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 		 * that case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 		if (cpumode == PERF_RECORD_MISC_KERNEL ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 		    cpumode == PERF_RECORD_MISC_GUEST_KERNEL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 			len -= ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 			if (len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 				pr_debug("Reducing len to %zu\n", len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 			} else if (dso__is_kcore(al.map->dso)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 				/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 				 * objdump cannot handle very large segments
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 				 * that may be found in kcore.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 				pr_debug("objdump failed for kcore");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 				pr_debug(" - skipping\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 				return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 				return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 		pr_debug("read_via_objdump failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 	/* The results should be identical */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 	if (memcmp(buf1, buf2, len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 		pr_debug("Bytes read differ from those read by objdump\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 		pr_debug("buf1 (dso):\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 		dump_buf(buf1, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 		pr_debug("buf2 (objdump):\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 		dump_buf(buf2, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	pr_debug("Bytes read match those read by objdump\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) static int process_sample_event(struct machine *machine,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 				struct evlist *evlist,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 				union perf_event *event, struct state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 	struct perf_sample sample;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 	struct thread *thread;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 	if (perf_evlist__parse_sample(evlist, event, &sample)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 		pr_debug("perf_evlist__parse_sample failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	thread = machine__findnew_thread(machine, sample.pid, sample.tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	if (!thread) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 		pr_debug("machine__findnew_thread failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 	ret = read_object_code(sample.ip, READLEN, sample.cpumode, thread, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 	thread__put(thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) static int process_event(struct machine *machine, struct evlist *evlist,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 			 union perf_event *event, struct state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 	if (event->header.type == PERF_RECORD_SAMPLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 		return process_sample_event(machine, evlist, event, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 	if (event->header.type == PERF_RECORD_THROTTLE ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 	    event->header.type == PERF_RECORD_UNTHROTTLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 	if (event->header.type < PERF_RECORD_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 		int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 		ret = machine__process_event(machine, event, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 			pr_debug("machine__process_event failed, event type %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 				 event->header.type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) static int process_events(struct machine *machine, struct evlist *evlist,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 			  struct state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 	union perf_event *event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 	struct mmap *md;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 	int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 	for (i = 0; i < evlist->core.nr_mmaps; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 		md = &evlist->mmap[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 		if (perf_mmap__read_init(&md->core) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 		while ((event = perf_mmap__read_event(&md->core)) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 			ret = process_event(machine, evlist, event, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 			perf_mmap__consume(&md->core);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 			if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 				return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 		perf_mmap__read_done(&md->core);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) static int comp(const void *a, const void *b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 	return *(int *)a - *(int *)b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) static void do_sort_something(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 	int buf[40960], i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 	for (i = 0; i < (int)ARRAY_SIZE(buf); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 		buf[i] = ARRAY_SIZE(buf) - i - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 	qsort(buf, ARRAY_SIZE(buf), sizeof(int), comp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 	for (i = 0; i < (int)ARRAY_SIZE(buf); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 		if (buf[i] != i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 			pr_debug("qsort failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) static void sort_something(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 	for (i = 0; i < 10; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 		do_sort_something();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) static void syscall_something(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 	int pipefd[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 	for (i = 0; i < 1000; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 		if (pipe(pipefd) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 			pr_debug("pipe failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 		close(pipefd[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 		close(pipefd[0]);
^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) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) static void fs_something(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 	const char *test_file_name = "temp-perf-code-reading-test-file--";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 	FILE *f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 	for (i = 0; i < 1000; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 		f = fopen(test_file_name, "w+");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 		if (f) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 			fclose(f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 			unlink(test_file_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) #ifdef __s390x__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) #include "header.h" // for get_cpuid()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) static const char *do_determine_event(bool excl_kernel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 	const char *event = excl_kernel ? "cycles:u" : "cycles";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) #ifdef __s390x__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 	char cpuid[128], model[16], model_c[16], cpum_cf_v[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 	unsigned int family;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 	int ret, cpum_cf_a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 	if (get_cpuid(cpuid, sizeof(cpuid)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 		goto out_clocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 	ret = sscanf(cpuid, "%*[^,],%u,%[^,],%[^,],%[^,],%x", &family, model_c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 		     model, cpum_cf_v, &cpum_cf_a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 	if (ret != 5)		 /* Not available */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 		goto out_clocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 	if (excl_kernel && (cpum_cf_a & 4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 		return event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 	if (!excl_kernel && (cpum_cf_a & 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 		return event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 	/* Fall through: missing authorization */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) out_clocks:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 	event = excl_kernel ? "cpu-clock:u" : "cpu-clock";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 	return event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) static void do_something(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 	fs_something();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 	sort_something();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 	syscall_something();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 	TEST_CODE_READING_OK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 	TEST_CODE_READING_NO_VMLINUX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 	TEST_CODE_READING_NO_KCORE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 	TEST_CODE_READING_NO_ACCESS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 	TEST_CODE_READING_NO_KERNEL_OBJ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) static int do_test_code_reading(bool try_kcore)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 	struct machine *machine;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 	struct thread *thread;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 	struct record_opts opts = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 		.mmap_pages	     = UINT_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 		.user_freq	     = UINT_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 		.user_interval	     = ULLONG_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 		.freq		     = 500,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 		.target		     = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 			.uses_mmap   = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 		},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 	struct state state = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 		.done_cnt = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 	struct perf_thread_map *threads = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 	struct perf_cpu_map *cpus = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 	struct evlist *evlist = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 	struct evsel *evsel = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 	int err = -1, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 	pid_t pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 	struct map *map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 	bool have_vmlinux, have_kcore, excl_kernel = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 	pid = getpid();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 	machine = machine__new_host();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 	machine->env = &perf_env;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 	ret = machine__create_kernel_maps(machine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 		pr_debug("machine__create_kernel_maps failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 		goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 	/* Force the use of kallsyms instead of vmlinux to try kcore */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 	if (try_kcore)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 		symbol_conf.kallsyms_name = "/proc/kallsyms";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 	/* Load kernel map */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 	map = machine__kernel_map(machine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 	ret = map__load(map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 		pr_debug("map__load failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 		goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 	have_vmlinux = dso__is_vmlinux(map->dso);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 	have_kcore = dso__is_kcore(map->dso);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 	/* 2nd time through we just try kcore */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 	if (try_kcore && !have_kcore)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 		return TEST_CODE_READING_NO_KCORE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 	/* No point getting kernel events if there is no kernel object */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 	if (!have_vmlinux && !have_kcore)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 		excl_kernel = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 	threads = thread_map__new_by_tid(pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 	if (!threads) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 		pr_debug("thread_map__new_by_tid failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 		goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 	ret = perf_event__synthesize_thread_map(NULL, threads,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 						perf_event__process, machine, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 		pr_debug("perf_event__synthesize_thread_map failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 		goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 	thread = machine__findnew_thread(machine, pid, pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 	if (!thread) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 		pr_debug("machine__findnew_thread failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 		goto out_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 	cpus = perf_cpu_map__new(NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 	if (!cpus) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 		pr_debug("perf_cpu_map__new failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 		goto out_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 	while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 		const char *str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 		evlist = evlist__new();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 		if (!evlist) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 			pr_debug("perf_evlist__new failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 			goto out_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 		perf_evlist__set_maps(&evlist->core, cpus, threads);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 		str = do_determine_event(excl_kernel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 		pr_debug("Parsing event '%s'\n", str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 		ret = parse_events(evlist, str, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 			pr_debug("parse_events failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 			goto out_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 		perf_evlist__config(evlist, &opts, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 		evsel = evlist__first(evlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 		evsel->core.attr.comm = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 		evsel->core.attr.disabled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 		evsel->core.attr.enable_on_exec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 		ret = evlist__open(evlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 			if (!excl_kernel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 				excl_kernel = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 				/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 				 * Both cpus and threads are now owned by evlist
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 				 * and will be freed by following perf_evlist__set_maps
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) 				 * call. Getting refference to keep them alive.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 				perf_cpu_map__get(cpus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 				perf_thread_map__get(threads);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 				perf_evlist__set_maps(&evlist->core, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 				evlist__delete(evlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 				evlist = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 			if (verbose > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) 				char errbuf[512];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 				evlist__strerror_open(evlist, errno, errbuf, sizeof(errbuf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 				pr_debug("perf_evlist__open() failed!\n%s\n", errbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 			goto out_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 	ret = evlist__mmap(evlist, UINT_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 		pr_debug("evlist__mmap failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 		goto out_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) 	evlist__enable(evlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 	do_something();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) 	evlist__disable(evlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) 	ret = process_events(machine, evlist, &state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) 		goto out_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 	if (!have_vmlinux && !have_kcore && !try_kcore)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 		err = TEST_CODE_READING_NO_KERNEL_OBJ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) 	else if (!have_vmlinux && !try_kcore)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 		err = TEST_CODE_READING_NO_VMLINUX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) 	else if (excl_kernel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) 		err = TEST_CODE_READING_NO_ACCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) 		err = TEST_CODE_READING_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) out_put:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) 	thread__put(thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) 	if (evlist) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) 		evlist__delete(evlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) 		perf_cpu_map__put(cpus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) 		perf_thread_map__put(threads);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) 	machine__delete_threads(machine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) 	machine__delete(machine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) int test__code_reading(struct test *test __maybe_unused, int subtest __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) 	ret = do_test_code_reading(false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) 	if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) 		ret = do_test_code_reading(true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) 	switch (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) 	case TEST_CODE_READING_OK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) 	case TEST_CODE_READING_NO_VMLINUX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) 		pr_debug("no vmlinux\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) 	case TEST_CODE_READING_NO_KCORE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) 		pr_debug("no kcore\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) 	case TEST_CODE_READING_NO_ACCESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) 		pr_debug("no access\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) 	case TEST_CODE_READING_NO_KERNEL_OBJ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) 		pr_debug("no kernel obj\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) }