cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

branch.c (3005B)


      1#include "util/map_symbol.h"
      2#include "util/branch.h"
      3#include <linux/kernel.h>
      4
      5static bool cross_area(u64 addr1, u64 addr2, int size)
      6{
      7	u64 align1, align2;
      8
      9	align1 = addr1 & ~(size - 1);
     10	align2 = addr2 & ~(size - 1);
     11
     12	return (align1 != align2) ? true : false;
     13}
     14
     15#define AREA_4K		4096
     16#define AREA_2M		(2 * 1024 * 1024)
     17
     18void branch_type_count(struct branch_type_stat *st, struct branch_flags *flags,
     19		       u64 from, u64 to)
     20{
     21	if (flags->type == PERF_BR_UNKNOWN || from == 0)
     22		return;
     23
     24	st->counts[flags->type]++;
     25
     26	if (flags->type == PERF_BR_COND) {
     27		if (to > from)
     28			st->cond_fwd++;
     29		else
     30			st->cond_bwd++;
     31	}
     32
     33	if (cross_area(from, to, AREA_2M))
     34		st->cross_2m++;
     35	else if (cross_area(from, to, AREA_4K))
     36		st->cross_4k++;
     37}
     38
     39const char *branch_type_name(int type)
     40{
     41	const char *branch_names[PERF_BR_MAX] = {
     42		"N/A",
     43		"COND",
     44		"UNCOND",
     45		"IND",
     46		"CALL",
     47		"IND_CALL",
     48		"RET",
     49		"SYSCALL",
     50		"SYSRET",
     51		"COND_CALL",
     52		"COND_RET",
     53		"ERET",
     54		"IRQ"
     55	};
     56
     57	if (type >= 0 && type < PERF_BR_MAX)
     58		return branch_names[type];
     59
     60	return NULL;
     61}
     62
     63void branch_type_stat_display(FILE *fp, struct branch_type_stat *st)
     64{
     65	u64 total = 0;
     66	int i;
     67
     68	for (i = 0; i < PERF_BR_MAX; i++)
     69		total += st->counts[i];
     70
     71	if (total == 0)
     72		return;
     73
     74	fprintf(fp, "\n#");
     75	fprintf(fp, "\n# Branch Statistics:");
     76	fprintf(fp, "\n#");
     77
     78	if (st->cond_fwd > 0) {
     79		fprintf(fp, "\n%8s: %5.1f%%",
     80			"COND_FWD",
     81			100.0 * (double)st->cond_fwd / (double)total);
     82	}
     83
     84	if (st->cond_bwd > 0) {
     85		fprintf(fp, "\n%8s: %5.1f%%",
     86			"COND_BWD",
     87			100.0 * (double)st->cond_bwd / (double)total);
     88	}
     89
     90	if (st->cross_4k > 0) {
     91		fprintf(fp, "\n%8s: %5.1f%%",
     92			"CROSS_4K",
     93			100.0 * (double)st->cross_4k / (double)total);
     94	}
     95
     96	if (st->cross_2m > 0) {
     97		fprintf(fp, "\n%8s: %5.1f%%",
     98			"CROSS_2M",
     99			100.0 * (double)st->cross_2m / (double)total);
    100	}
    101
    102	for (i = 0; i < PERF_BR_MAX; i++) {
    103		if (st->counts[i] > 0)
    104			fprintf(fp, "\n%8s: %5.1f%%",
    105				branch_type_name(i),
    106				100.0 *
    107				(double)st->counts[i] / (double)total);
    108	}
    109}
    110
    111static int count_str_scnprintf(int idx, const char *str, char *bf, int size)
    112{
    113	return scnprintf(bf, size, "%s%s", (idx) ? " " : " (", str);
    114}
    115
    116int branch_type_str(struct branch_type_stat *st, char *bf, int size)
    117{
    118	int i, j = 0, printed = 0;
    119	u64 total = 0;
    120
    121	for (i = 0; i < PERF_BR_MAX; i++)
    122		total += st->counts[i];
    123
    124	if (total == 0)
    125		return 0;
    126
    127	if (st->cond_fwd > 0)
    128		printed += count_str_scnprintf(j++, "COND_FWD", bf + printed, size - printed);
    129
    130	if (st->cond_bwd > 0)
    131		printed += count_str_scnprintf(j++, "COND_BWD", bf + printed, size - printed);
    132
    133	for (i = 0; i < PERF_BR_MAX; i++) {
    134		if (i == PERF_BR_COND)
    135			continue;
    136
    137		if (st->counts[i] > 0)
    138			printed += count_str_scnprintf(j++, branch_type_name(i), bf + printed, size - printed);
    139	}
    140
    141	if (st->cross_4k > 0)
    142		printed += count_str_scnprintf(j++, "CROSS_4K", bf + printed, size - printed);
    143
    144	if (st->cross_2m > 0)
    145		printed += count_str_scnprintf(j++, "CROSS_2M", bf + printed, size - printed);
    146
    147	return printed;
    148}