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

ibumad_user.c (3439B)


      1// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
      2
      3/*
      4 * ibumad BPF sample user side
      5 *
      6 * This program is free software; you can redistribute it and/or
      7 * modify it under the terms of version 2 of the GNU General Public
      8 * License as published by the Free Software Foundation.
      9 *
     10 * Copyright(c) 2018 Ira Weiny, Intel Corporation
     11 */
     12
     13#include <linux/bpf.h>
     14#include <signal.h>
     15#include <stdio.h>
     16#include <stdlib.h>
     17#include <string.h>
     18#include <unistd.h>
     19#include <sys/types.h>
     20#include <limits.h>
     21
     22#include <getopt.h>
     23#include <net/if.h>
     24
     25#include <bpf/bpf.h>
     26#include "bpf_util.h"
     27#include <bpf/libbpf.h>
     28
     29static struct bpf_link *tp_links[3];
     30static struct bpf_object *obj;
     31static int map_fd[2];
     32static int tp_cnt;
     33
     34static void dump_counts(int fd)
     35{
     36	__u32 key;
     37	__u64 value;
     38
     39	for (key = 0; key < 256; key++) {
     40		if (bpf_map_lookup_elem(fd, &key, &value)) {
     41			printf("failed to read key %u\n", key);
     42			continue;
     43		}
     44		if (value)
     45			printf("0x%02x : %llu\n", key, value);
     46	}
     47}
     48
     49static void dump_all_counts(void)
     50{
     51	printf("Read 'Class : count'\n");
     52	dump_counts(map_fd[0]);
     53	printf("Write 'Class : count'\n");
     54	dump_counts(map_fd[1]);
     55}
     56
     57static void dump_exit(int sig)
     58{
     59	dump_all_counts();
     60	/* Detach tracepoints */
     61	while (tp_cnt)
     62		bpf_link__destroy(tp_links[--tp_cnt]);
     63
     64	bpf_object__close(obj);
     65	exit(0);
     66}
     67
     68static const struct option long_options[] = {
     69	{"help",      no_argument,       NULL, 'h'},
     70	{"delay",     required_argument, NULL, 'd'},
     71};
     72
     73static void usage(char *cmd)
     74{
     75	printf("eBPF test program to count packets from various IP addresses\n"
     76		"Usage: %s <options>\n"
     77		"       --help,   -h  this menu\n"
     78		"       --delay,  -d  <delay>  wait <delay> sec between prints [1 - 1000000]\n"
     79		, cmd
     80		);
     81}
     82
     83int main(int argc, char **argv)
     84{
     85	struct bpf_program *prog;
     86	unsigned long delay = 5;
     87	char filename[256];
     88	int longindex = 0;
     89	int opt, err = -1;
     90
     91	while ((opt = getopt_long(argc, argv, "hd:rSw",
     92				  long_options, &longindex)) != -1) {
     93		switch (opt) {
     94		case 'd':
     95			delay = strtoul(optarg, NULL, 0);
     96			if (delay == ULONG_MAX || delay < 0 ||
     97			    delay > 1000000) {
     98				fprintf(stderr, "ERROR: invalid delay : %s\n",
     99					optarg);
    100				usage(argv[0]);
    101				return 1;
    102			}
    103			break;
    104		default:
    105		case 'h':
    106			usage(argv[0]);
    107			return 1;
    108		}
    109	}
    110
    111	/* Do one final dump when exiting */
    112	signal(SIGINT, dump_exit);
    113	signal(SIGTERM, dump_exit);
    114
    115	snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
    116	obj = bpf_object__open_file(filename, NULL);
    117	if (libbpf_get_error(obj)) {
    118		fprintf(stderr, "ERROR: opening BPF object file failed\n");
    119		return err;
    120	}
    121
    122	/* load BPF program */
    123	if (bpf_object__load(obj)) {
    124		fprintf(stderr, "ERROR: loading BPF object file failed\n");
    125		goto cleanup;
    126	}
    127
    128	map_fd[0] = bpf_object__find_map_fd_by_name(obj, "read_count");
    129	map_fd[1] = bpf_object__find_map_fd_by_name(obj, "write_count");
    130	if (map_fd[0] < 0 || map_fd[1] < 0) {
    131		fprintf(stderr, "ERROR: finding a map in obj file failed\n");
    132		goto cleanup;
    133	}
    134
    135	bpf_object__for_each_program(prog, obj) {
    136		tp_links[tp_cnt] = bpf_program__attach(prog);
    137		if (libbpf_get_error(tp_links[tp_cnt])) {
    138			fprintf(stderr, "ERROR: bpf_program__attach failed\n");
    139			tp_links[tp_cnt] = NULL;
    140			goto cleanup;
    141		}
    142		tp_cnt++;
    143	}
    144
    145	while (1) {
    146		sleep(delay);
    147		dump_all_counts();
    148	}
    149	err = 0;
    150
    151cleanup:
    152	/* Detach tracepoints */
    153	while (tp_cnt)
    154		bpf_link__destroy(tp_links[--tp_cnt]);
    155
    156	bpf_object__close(obj);
    157	return err;
    158}