close
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions src/kerninfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,51 @@

#include <stdio.h>

void get_vendor(char *vendor) {
unsigned int a[4];

asm (
/* %rbx must be preserved. */
"mov %%rbx, %%rdi\n"
"cpuid\n"
"xchg %%rdi, %%rbx\n"
: "=a"(a[0]), "=D"(a[1]), "=c"(a[2]), "=d"(a[3])
: "a"(0)
);
strncpy(&vendor[0], (char *)&a[1], 4);
strncpy(&vendor[4], (char *)&a[3], 4);
strncpy(&vendor[8], (char *)&a[2], 4);
}

int is_amd_arch(void) {
static int amd = -1; /* -1: Unknown, 1: Yes, 0: No */
char vendor[13] = {0};

if (amd != -1)
return amd;

get_vendor(vendor);
amd = strcmp(vendor, "AuthenticAMD") ? 0 : 1;
return amd;
}

void get_pmu_string(char *pmu_name) {
FILE *f;
size_t retval;

if (is_amd_arch()) {
f = fopen("/sys/bus/event_source/devices/ibs_op", "r");
if (!f) {
fprintf(stderr, "WARNING: Unable to open '/sys/bus/event_source/devices/ibs_op'. "
"Using software events.\n");
strcpy(pmu_name, "invalid");
return;
}
fclose(f);
strcpy(pmu_name, "ibs_op");
return;
}

f = fopen("/sys/devices/cpu/caps/pmu_name", "r");
if(!f) {
fprintf(stderr, "WARNING: Unable to open '/sys/devices/cpu/caps/pmu_name'. Using software events.\n");
Expand Down
35 changes: 35 additions & 0 deletions src/setup_bpf.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,35 @@ static int single_tma_event(struct event *e, struct event *leader,

#else

/* Return value: >0: Valid, -1: Error */
static int get_ibs_op_type(void) {
static int type = -1; /* -1 : Unknown, 0: Failed to read first time, >0: Valid */
FILE *fp;
int ret;

if (type != -1) {
if (!type)
return -1;
return type;
}

fp = fopen("/sys/bus/event_source/devices/ibs_op/type", "r");
if (!fp) {
fprintf(stderr, "Failed to find ibs_op// pmu sysfs. [%m]\n");
type = 0;
return -1;
}

ret = fscanf(fp, "%d", &type);
fclose(fp);
if (ret != 1) {
fprintf(stderr, "Failed to read ibs_op// type. [%m]\n");
type = 0;
return -1;
}
return type;
}

/**
single_insn_event - Handles a single CPU, PMU, socket event.
Returns:
Expand Down Expand Up @@ -177,6 +206,12 @@ static int single_insn_event(int cpu, int pid) {
} else if(strncmp(bpf_info->pmu_name, "sapphire_rapids", 7) == 0) {
attr.type = PERF_TYPE_RAW;
attr.config = 0x00c0;
} else if(strncmp(bpf_info->pmu_name, "ibs_op", 6) == 0) {
attr.type = get_ibs_op_type();
if (attr.type < 0)
return -1;
attr.config = 0x80000;
attr.exclude_guest = 0;
} else {
attr.type = PERF_TYPE_SOFTWARE;
attr.config = PERF_COUNT_SW_CPU_CLOCK;
Expand Down