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

cpuidle-set.c (4269B)


      1// SPDX-License-Identifier: GPL-2.0
      2#include <unistd.h>
      3#include <stdio.h>
      4#include <errno.h>
      5#include <stdlib.h>
      6#include <limits.h>
      7#include <string.h>
      8#include <ctype.h>
      9#include <getopt.h>
     10
     11#include <cpufreq.h>
     12#include <cpuidle.h>
     13
     14#include "helpers/helpers.h"
     15
     16static struct option info_opts[] = {
     17     {"disable",	required_argument,		NULL, 'd'},
     18     {"enable",		required_argument,		NULL, 'e'},
     19     {"disable-by-latency", required_argument,		NULL, 'D'},
     20     {"enable-all",	no_argument,			NULL, 'E'},
     21     { },
     22};
     23
     24
     25int cmd_idle_set(int argc, char **argv)
     26{
     27	extern char *optarg;
     28	extern int optind, opterr, optopt;
     29	int ret = 0, cont = 1, param = 0, disabled;
     30	unsigned long long latency = 0, state_latency;
     31	unsigned int cpu = 0, idlestate = 0, idlestates = 0;
     32	char *endptr;
     33
     34	do {
     35		ret = getopt_long(argc, argv, "d:e:ED:", info_opts, NULL);
     36		if (ret == -1)
     37			break;
     38		switch (ret) {
     39		case '?':
     40			param = '?';
     41			cont = 0;
     42			break;
     43		case 'd':
     44			if (param) {
     45				param = -1;
     46				cont = 0;
     47				break;
     48			}
     49			param = ret;
     50			idlestate = atoi(optarg);
     51			break;
     52		case 'e':
     53			if (param) {
     54				param = -1;
     55				cont = 0;
     56				break;
     57			}
     58			param = ret;
     59			idlestate = atoi(optarg);
     60			break;
     61		case 'D':
     62			if (param) {
     63				param = -1;
     64				cont = 0;
     65				break;
     66			}
     67			param = ret;
     68			latency = strtoull(optarg, &endptr, 10);
     69			if (*endptr != '\0') {
     70				printf(_("Bad latency value: %s\n"), optarg);
     71				exit(EXIT_FAILURE);
     72			}
     73			break;
     74		case 'E':
     75			if (param) {
     76				param = -1;
     77				cont = 0;
     78				break;
     79			}
     80			param = ret;
     81			break;
     82		case -1:
     83			cont = 0;
     84			break;
     85		}
     86	} while (cont);
     87
     88	switch (param) {
     89	case -1:
     90		printf(_("You can't specify more than one "
     91			 "output-specific argument\n"));
     92		exit(EXIT_FAILURE);
     93	case '?':
     94		printf(_("invalid or unknown argument\n"));
     95		exit(EXIT_FAILURE);
     96	}
     97
     98	get_cpustate();
     99
    100	/* Default is: set all CPUs */
    101	if (bitmask_isallclear(cpus_chosen))
    102		bitmask_setall(cpus_chosen);
    103
    104	for (cpu = bitmask_first(cpus_chosen);
    105	     cpu <= bitmask_last(cpus_chosen); cpu++) {
    106
    107		if (!bitmask_isbitset(cpus_chosen, cpu))
    108			continue;
    109
    110		if (cpupower_is_cpu_online(cpu) != 1)
    111			continue;
    112
    113		idlestates = cpuidle_state_count(cpu);
    114		if (idlestates <= 0)
    115			continue;
    116
    117		switch (param) {
    118		case 'd':
    119			ret = cpuidle_state_disable(cpu, idlestate, 1);
    120			if (ret == 0)
    121		printf(_("Idlestate %u disabled on CPU %u\n"),  idlestate, cpu);
    122			else if (ret == -1)
    123		printf(_("Idlestate %u not available on CPU %u\n"),
    124		       idlestate, cpu);
    125			else if (ret == -2)
    126		printf(_("Idlestate disabling not supported by kernel\n"));
    127			else
    128		printf(_("Idlestate %u not disabled on CPU %u\n"),
    129		       idlestate, cpu);
    130			break;
    131		case 'e':
    132			ret = cpuidle_state_disable(cpu, idlestate, 0);
    133			if (ret == 0)
    134		printf(_("Idlestate %u enabled on CPU %u\n"),  idlestate, cpu);
    135			else if (ret == -1)
    136		printf(_("Idlestate %u not available on CPU %u\n"),
    137		       idlestate, cpu);
    138			else if (ret == -2)
    139		printf(_("Idlestate enabling not supported by kernel\n"));
    140			else
    141		printf(_("Idlestate %u not enabled on CPU %u\n"),
    142		       idlestate, cpu);
    143			break;
    144		case 'D':
    145			for (idlestate = 0; idlestate < idlestates; idlestate++) {
    146				disabled = cpuidle_is_state_disabled
    147					(cpu, idlestate);
    148				state_latency = cpuidle_state_latency
    149					(cpu, idlestate);
    150				if (disabled == 1) {
    151					if (latency > state_latency){
    152						ret = cpuidle_state_disable
    153							(cpu, idlestate, 0);
    154						if (ret == 0)
    155		printf(_("Idlestate %u enabled on CPU %u\n"),  idlestate, cpu);
    156					}
    157					continue;
    158				}
    159				if (latency <= state_latency){
    160					ret = cpuidle_state_disable
    161						(cpu, idlestate, 1);
    162					if (ret == 0)
    163		printf(_("Idlestate %u disabled on CPU %u\n"), idlestate, cpu);
    164				}
    165			}
    166			break;
    167		case 'E':
    168			for (idlestate = 0; idlestate < idlestates; idlestate++) {
    169				disabled = cpuidle_is_state_disabled
    170					(cpu, idlestate);
    171				if (disabled == 1) {
    172					ret = cpuidle_state_disable
    173						(cpu, idlestate, 0);
    174					if (ret == 0)
    175		printf(_("Idlestate %u enabled on CPU %u\n"), idlestate, cpu);
    176				}
    177			}
    178			break;
    179		default:
    180			/* Not reachable with proper args checking */
    181			printf(_("Invalid or unknown argument\n"));
    182			exit(EXIT_FAILURE);
    183			break;
    184		}
    185	}
    186
    187	print_offline_cpus();
    188	return EXIT_SUCCESS;
    189}