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

cache_shape.c (2380B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Copyright 2017, Michael Ellerman, IBM Corp.
      4 */
      5
      6#include <elf.h>
      7#include <errno.h>
      8#include <fcntl.h>
      9#include <link.h>
     10#include <stdio.h>
     11#include <stdlib.h>
     12#include <string.h>
     13#include <sys/stat.h>
     14#include <sys/types.h>
     15#include <sys/wait.h>
     16#include <unistd.h>
     17
     18#include "utils.h"
     19
     20#ifndef AT_L1I_CACHESIZE
     21#define AT_L1I_CACHESIZE	40
     22#define AT_L1I_CACHEGEOMETRY	41
     23#define AT_L1D_CACHESIZE	42
     24#define AT_L1D_CACHEGEOMETRY	43
     25#define AT_L2_CACHESIZE		44
     26#define AT_L2_CACHEGEOMETRY	45
     27#define AT_L3_CACHESIZE		46
     28#define AT_L3_CACHEGEOMETRY	47
     29#endif
     30
     31static void print_size(const char *label, uint32_t val)
     32{
     33	printf("%s cache size: %#10x %10dB %10dK\n", label, val, val, val / 1024);
     34}
     35
     36static void print_geo(const char *label, uint32_t val)
     37{
     38	uint16_t assoc;
     39
     40	printf("%s line size:  %#10x       ", label, val & 0xFFFF);
     41
     42	assoc = val >> 16;
     43	if (assoc)
     44		printf("%u-way", assoc);
     45	else
     46		printf("fully");
     47
     48	printf(" associative\n");
     49}
     50
     51static int test_cache_shape()
     52{
     53	static char buffer[4096];
     54	ElfW(auxv_t) *p;
     55	int found;
     56
     57	FAIL_IF(read_auxv(buffer, sizeof(buffer)));
     58
     59	found = 0;
     60
     61	p = find_auxv_entry(AT_L1I_CACHESIZE, buffer);
     62	if (p) {
     63		found++;
     64		print_size("L1I ", (uint32_t)p->a_un.a_val);
     65	}
     66
     67	p = find_auxv_entry(AT_L1I_CACHEGEOMETRY, buffer);
     68	if (p) {
     69		found++;
     70		print_geo("L1I ", (uint32_t)p->a_un.a_val);
     71	}
     72
     73	p = find_auxv_entry(AT_L1D_CACHESIZE, buffer);
     74	if (p) {
     75		found++;
     76		print_size("L1D ", (uint32_t)p->a_un.a_val);
     77	}
     78
     79	p = find_auxv_entry(AT_L1D_CACHEGEOMETRY, buffer);
     80	if (p) {
     81		found++;
     82		print_geo("L1D ", (uint32_t)p->a_un.a_val);
     83	}
     84
     85	p = find_auxv_entry(AT_L2_CACHESIZE, buffer);
     86	if (p) {
     87		found++;
     88		print_size("L2  ", (uint32_t)p->a_un.a_val);
     89	}
     90
     91	p = find_auxv_entry(AT_L2_CACHEGEOMETRY, buffer);
     92	if (p) {
     93		found++;
     94		print_geo("L2  ", (uint32_t)p->a_un.a_val);
     95	}
     96
     97	p = find_auxv_entry(AT_L3_CACHESIZE, buffer);
     98	if (p) {
     99		found++;
    100		print_size("L3  ", (uint32_t)p->a_un.a_val);
    101	}
    102
    103	p = find_auxv_entry(AT_L3_CACHEGEOMETRY, buffer);
    104	if (p) {
    105		found++;
    106		print_geo("L3  ", (uint32_t)p->a_un.a_val);
    107	}
    108
    109	/* If we found none we're probably on a system where they don't exist */
    110	SKIP_IF(found == 0);
    111
    112	/* But if we found any, we expect to find them all */
    113	FAIL_IF(found != 8);
    114
    115	return 0;
    116}
    117
    118int main(void)
    119{
    120	return test_harness(test_cache_shape, "cache_shape");
    121}