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

isst-daemon.c (5403B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Intel Speed Select -- Allow speed select to daemonize
      4 * Copyright (c) 2022 Intel Corporation.
      5 */
      6
      7#include <stdio.h>
      8#include <stdlib.h>
      9#include <stdarg.h>
     10#include <string.h>
     11#include <unistd.h>
     12#include <fcntl.h>
     13#include <sys/file.h>
     14#include <sys/types.h>
     15#include <sys/stat.h>
     16#include <errno.h>
     17#include <getopt.h>
     18#include <signal.h>
     19#include <time.h>
     20
     21#include "isst.h"
     22
     23static int per_package_levels_info[MAX_PACKAGE_COUNT][MAX_DIE_PER_PACKAGE];
     24static time_t per_package_levels_tm[MAX_PACKAGE_COUNT][MAX_DIE_PER_PACKAGE];
     25
     26static void init_levels(void)
     27{
     28	int i, j;
     29
     30	for (i = 0; i < MAX_PACKAGE_COUNT; ++i)
     31		for (j = 0; j < MAX_DIE_PER_PACKAGE; ++j)
     32			per_package_levels_info[i][j] = -1;
     33}
     34
     35void process_level_change(int cpu)
     36{
     37	struct isst_pkg_ctdp_level_info ctdp_level;
     38	int pkg_id = get_physical_package_id(cpu);
     39	int die_id = get_physical_die_id(cpu);
     40	struct isst_pkg_ctdp pkg_dev;
     41	time_t tm;
     42	int ret;
     43
     44	if (pkg_id >= MAX_PACKAGE_COUNT || die_id > MAX_DIE_PER_PACKAGE) {
     45		debug_printf("Invalid package/die info for cpu:%d\n", cpu);
     46		return;
     47	}
     48
     49	tm = time(NULL);
     50	if (tm - per_package_levels_tm[pkg_id][die_id] < 2 )
     51		return;
     52
     53	per_package_levels_tm[pkg_id][die_id] = tm;
     54
     55	ret = isst_get_ctdp_levels(cpu, &pkg_dev);
     56	if (ret) {
     57		debug_printf("Can't get tdp levels for cpu:%d\n", cpu);
     58		return;
     59	}
     60
     61	debug_printf("Get Config level %d pkg:%d die:%d current_level:%d \n", cpu,
     62		      pkg_id, die_id, pkg_dev.current_level);
     63
     64	if (pkg_dev.locked) {
     65		debug_printf("config TDP s locked \n");
     66		return;
     67	}
     68
     69	if (per_package_levels_info[pkg_id][die_id] == pkg_dev.current_level)
     70		return;
     71
     72	debug_printf("**Config level change for cpu:%d pkg:%d die:%d from %d to %d\n",
     73		      cpu, pkg_id, die_id, per_package_levels_info[pkg_id][die_id],
     74		      pkg_dev.current_level);
     75
     76	per_package_levels_info[pkg_id][die_id] = pkg_dev.current_level;
     77
     78	ctdp_level.core_cpumask_size =
     79		alloc_cpu_set(&ctdp_level.core_cpumask);
     80	ret = isst_get_coremask_info(cpu, pkg_dev.current_level, &ctdp_level);
     81	if (ret) {
     82		free_cpu_set(ctdp_level.core_cpumask);
     83		debug_printf("Can't get core_mask:%d\n", cpu);
     84		return;
     85	}
     86
     87	if (ctdp_level.cpu_count) {
     88		int i, max_cpus = get_topo_max_cpus();
     89		for (i = 0; i < max_cpus; ++i) {
     90			if (pkg_id != get_physical_package_id(i) || die_id != get_physical_die_id(i))
     91				continue;
     92			if (CPU_ISSET_S(i, ctdp_level.core_cpumask_size, ctdp_level.core_cpumask)) {
     93				fprintf(stderr, "online cpu %d\n", i);
     94				set_cpu_online_offline(i, 1);
     95			} else {
     96				fprintf(stderr, "offline cpu %d\n", i);
     97				set_cpu_online_offline(i, 0);
     98			}
     99		}
    100	}
    101
    102	free_cpu_set(ctdp_level.core_cpumask);
    103}
    104
    105static void _poll_for_config_change(int cpu, void *arg1, void *arg2,
    106				    void *arg3, void *arg4)
    107{
    108	process_level_change(cpu);
    109}
    110
    111static void poll_for_config_change(void)
    112{
    113	for_each_online_package_in_set(_poll_for_config_change, NULL, NULL,
    114				       NULL, NULL);
    115}
    116
    117static int done = 0;
    118static int pid_file_handle;
    119
    120static void signal_handler(int sig)
    121{
    122	switch (sig) {
    123	case SIGINT:
    124	case SIGTERM:
    125		done = 1;
    126		hfi_exit();
    127		exit(0);
    128		break;
    129	default:
    130		break;
    131	}
    132}
    133
    134static void daemonize(char *rundir, char *pidfile)
    135{
    136	int pid, sid, i;
    137	char str[10];
    138	struct sigaction sig_actions;
    139	sigset_t sig_set;
    140	int ret;
    141
    142	if (getppid() == 1)
    143		return;
    144
    145	sigemptyset(&sig_set);
    146	sigaddset(&sig_set, SIGCHLD);
    147	sigaddset(&sig_set, SIGTSTP);
    148	sigaddset(&sig_set, SIGTTOU);
    149	sigaddset(&sig_set, SIGTTIN);
    150	sigprocmask(SIG_BLOCK, &sig_set, NULL);
    151
    152	sig_actions.sa_handler = signal_handler;
    153	sigemptyset(&sig_actions.sa_mask);
    154	sig_actions.sa_flags = 0;
    155
    156	sigaction(SIGHUP, &sig_actions, NULL);
    157	sigaction(SIGTERM, &sig_actions, NULL);
    158	sigaction(SIGINT, &sig_actions, NULL);
    159
    160	pid = fork();
    161	if (pid < 0) {
    162		/* Could not fork */
    163		exit(EXIT_FAILURE);
    164	}
    165	if (pid > 0)
    166		exit(EXIT_SUCCESS);
    167
    168	umask(027);
    169
    170	sid = setsid();
    171	if (sid < 0)
    172		exit(EXIT_FAILURE);
    173
    174	/* close all descriptors */
    175	for (i = getdtablesize(); i >= 0; --i)
    176		close(i);
    177
    178	i = open("/dev/null", O_RDWR);
    179	ret = dup(i);
    180	if (ret == -1)
    181		exit(EXIT_FAILURE);
    182
    183	ret = dup(i);
    184	if (ret == -1)
    185		exit(EXIT_FAILURE);
    186
    187	ret = chdir(rundir);
    188	if (ret == -1)
    189		exit(EXIT_FAILURE);
    190
    191	pid_file_handle = open(pidfile, O_RDWR | O_CREAT, 0600);
    192	if (pid_file_handle == -1) {
    193		/* Couldn't open lock file */
    194		exit(1);
    195	}
    196	/* Try to lock file */
    197#ifdef LOCKF_SUPPORT
    198	if (lockf(pid_file_handle, F_TLOCK, 0) == -1) {
    199#else
    200	if (flock(pid_file_handle, LOCK_EX|LOCK_NB) < 0) {
    201#endif
    202		/* Couldn't get lock on lock file */
    203		fprintf(stderr, "Couldn't get lock file %d\n", getpid());
    204		exit(1);
    205	}
    206	snprintf(str, sizeof(str), "%d\n", getpid());
    207	ret = write(pid_file_handle, str, strlen(str));
    208	if (ret == -1)
    209		exit(EXIT_FAILURE);
    210
    211	close(i);
    212}
    213
    214int isst_daemon(int debug_mode, int poll_interval, int no_daemon)
    215{
    216	int ret;
    217
    218	if (!no_daemon && poll_interval < 0 && !debug_mode) {
    219		fprintf(stderr, "OOB mode is enabled and will run as daemon\n");
    220		daemonize((char *) "/tmp/",
    221				(char *)"/tmp/hfi-events.pid");
    222	} else {
    223		signal(SIGINT, signal_handler);
    224	}
    225
    226	init_levels();
    227
    228	if (poll_interval < 0) {
    229		ret = hfi_main();
    230		if (ret) {
    231			fprintf(stderr, "HFI initialization failed\n");
    232		}
    233		fprintf(stderr, "Must specify poll-interval\n");
    234		return ret;
    235	}
    236
    237	debug_printf("Starting loop\n");
    238	while (!done) {
    239		sleep(poll_interval);
    240		poll_for_config_change();
    241	}
    242
    243	return 0;
    244}