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

header.c (1922B)


      1#include <stdio.h>
      2#include <stdlib.h>
      3#include <perf/cpumap.h>
      4#include <util/cpumap.h>
      5#include <internal/cpumap.h>
      6#include <api/fs/fs.h>
      7#include <errno.h>
      8#include "debug.h"
      9#include "header.h"
     10
     11#define MIDR "/regs/identification/midr_el1"
     12#define MIDR_SIZE 19
     13#define MIDR_REVISION_MASK      0xf
     14#define MIDR_VARIANT_SHIFT      20
     15#define MIDR_VARIANT_MASK       (0xf << MIDR_VARIANT_SHIFT)
     16
     17static int _get_cpuid(char *buf, size_t sz, struct perf_cpu_map *cpus)
     18{
     19	const char *sysfs = sysfs__mountpoint();
     20	u64 midr = 0;
     21	int cpu;
     22
     23	if (!sysfs || sz < MIDR_SIZE)
     24		return EINVAL;
     25
     26	cpus = perf_cpu_map__get(cpus);
     27
     28	for (cpu = 0; cpu < perf_cpu_map__nr(cpus); cpu++) {
     29		char path[PATH_MAX];
     30		FILE *file;
     31
     32		scnprintf(path, PATH_MAX, "%s/devices/system/cpu/cpu%d"MIDR,
     33				sysfs, cpus->map[cpu]);
     34
     35		file = fopen(path, "r");
     36		if (!file) {
     37			pr_debug("fopen failed for file %s\n", path);
     38			continue;
     39		}
     40
     41		if (!fgets(buf, MIDR_SIZE, file)) {
     42			fclose(file);
     43			continue;
     44		}
     45		fclose(file);
     46
     47		/* Ignore/clear Variant[23:20] and
     48		 * Revision[3:0] of MIDR
     49		 */
     50		midr = strtoul(buf, NULL, 16);
     51		midr &= (~(MIDR_VARIANT_MASK | MIDR_REVISION_MASK));
     52		scnprintf(buf, MIDR_SIZE, "0x%016lx", midr);
     53		/* got midr break loop */
     54		break;
     55	}
     56
     57	perf_cpu_map__put(cpus);
     58
     59	if (!midr)
     60		return EINVAL;
     61
     62	return 0;
     63}
     64
     65int get_cpuid(char *buf, size_t sz)
     66{
     67	struct perf_cpu_map *cpus = perf_cpu_map__new(NULL);
     68	int ret;
     69
     70	if (!cpus)
     71		return EINVAL;
     72
     73	ret = _get_cpuid(buf, sz, cpus);
     74
     75	perf_cpu_map__put(cpus);
     76
     77	return ret;
     78}
     79
     80char *get_cpuid_str(struct perf_pmu *pmu)
     81{
     82	char *buf = NULL;
     83	int res;
     84
     85	if (!pmu || !pmu->cpus)
     86		return NULL;
     87
     88	buf = malloc(MIDR_SIZE);
     89	if (!buf)
     90		return NULL;
     91
     92	/* read midr from list of cpus mapped to this pmu */
     93	res = _get_cpuid(buf, MIDR_SIZE, pmu->cpus);
     94	if (res) {
     95		pr_err("failed to get cpuid string for PMU %s\n", pmu->name);
     96		free(buf);
     97		buf = NULL;
     98	}
     99
    100	return buf;
    101}