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

smt.c (1695B)


      1#include <stdio.h>
      2#include <stdlib.h>
      3#include <unistd.h>
      4#include <linux/bitops.h>
      5#include "api/fs/fs.h"
      6#include "smt.h"
      7
      8/**
      9 * hweight_str - Returns the number of bits set in str. Stops at first non-hex
     10 *	       or ',' character.
     11 */
     12static int hweight_str(char *str)
     13{
     14	int result = 0;
     15
     16	while (*str) {
     17		switch (*str++) {
     18		case '0':
     19		case ',':
     20			break;
     21		case '1':
     22		case '2':
     23		case '4':
     24		case '8':
     25			result++;
     26			break;
     27		case '3':
     28		case '5':
     29		case '6':
     30		case '9':
     31		case 'a':
     32		case 'A':
     33		case 'c':
     34		case 'C':
     35			result += 2;
     36			break;
     37		case '7':
     38		case 'b':
     39		case 'B':
     40		case 'd':
     41		case 'D':
     42		case 'e':
     43		case 'E':
     44			result += 3;
     45			break;
     46		case 'f':
     47		case 'F':
     48			result += 4;
     49			break;
     50		default:
     51			goto done;
     52		}
     53	}
     54done:
     55	return result;
     56}
     57
     58int smt_on(void)
     59{
     60	static bool cached;
     61	static int cached_result;
     62	int cpu;
     63	int ncpu;
     64
     65	if (cached)
     66		return cached_result;
     67
     68	if (sysfs__read_int("devices/system/cpu/smt/active", &cached_result) >= 0) {
     69		cached = true;
     70		return cached_result;
     71	}
     72
     73	cached_result = 0;
     74	ncpu = sysconf(_SC_NPROCESSORS_CONF);
     75	for (cpu = 0; cpu < ncpu; cpu++) {
     76		unsigned long long siblings;
     77		char *str;
     78		size_t strlen;
     79		char fn[256];
     80
     81		snprintf(fn, sizeof fn,
     82			"devices/system/cpu/cpu%d/topology/thread_siblings", cpu);
     83		if (sysfs__read_str(fn, &str, &strlen) < 0) {
     84			snprintf(fn, sizeof fn,
     85				"devices/system/cpu/cpu%d/topology/core_cpus", cpu);
     86			if (sysfs__read_str(fn, &str, &strlen) < 0)
     87				continue;
     88		}
     89		/* Entry is hex, but does not have 0x, so need custom parser */
     90		siblings = hweight_str(str);
     91		free(str);
     92		if (siblings > 1) {
     93			cached_result = 1;
     94			break;
     95		}
     96	}
     97	cached = true;
     98	return cached_result;
     99}