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

cpu.c (2009B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/* -*- linux-c -*- ------------------------------------------------------- *
      3 *
      4 *   Copyright (C) 1991, 1992 Linus Torvalds
      5 *   Copyright 2007-2008 rPath, Inc. - All Rights Reserved
      6 *
      7 * ----------------------------------------------------------------------- */
      8
      9/*
     10 * arch/x86/boot/cpu.c
     11 *
     12 * Check for obligatory CPU features and abort if the features are not
     13 * present.
     14 */
     15
     16#include "boot.h"
     17#ifdef CONFIG_X86_FEATURE_NAMES
     18#include "cpustr.h"
     19#endif
     20
     21static char *cpu_name(int level)
     22{
     23	static char buf[6];
     24
     25	if (level == 64) {
     26		return "x86-64";
     27	} else {
     28		if (level == 15)
     29			level = 6;
     30		sprintf(buf, "i%d86", level);
     31		return buf;
     32	}
     33}
     34
     35static void show_cap_strs(u32 *err_flags)
     36{
     37	int i, j;
     38#ifdef CONFIG_X86_FEATURE_NAMES
     39	const unsigned char *msg_strs = (const unsigned char *)x86_cap_strs;
     40	for (i = 0; i < NCAPINTS; i++) {
     41		u32 e = err_flags[i];
     42		for (j = 0; j < 32; j++) {
     43			if (msg_strs[0] < i ||
     44			    (msg_strs[0] == i && msg_strs[1] < j)) {
     45				/* Skip to the next string */
     46				msg_strs += 2;
     47				while (*msg_strs++)
     48					;
     49			}
     50			if (e & 1) {
     51				if (msg_strs[0] == i &&
     52				    msg_strs[1] == j &&
     53				    msg_strs[2])
     54					printf("%s ", msg_strs+2);
     55				else
     56					printf("%d:%d ", i, j);
     57			}
     58			e >>= 1;
     59		}
     60	}
     61#else
     62	for (i = 0; i < NCAPINTS; i++) {
     63		u32 e = err_flags[i];
     64		for (j = 0; j < 32; j++) {
     65			if (e & 1)
     66				printf("%d:%d ", i, j);
     67			e >>= 1;
     68		}
     69	}
     70#endif
     71}
     72
     73int validate_cpu(void)
     74{
     75	u32 *err_flags;
     76	int cpu_level, req_level;
     77
     78	check_cpu(&cpu_level, &req_level, &err_flags);
     79
     80	if (cpu_level < req_level) {
     81		printf("This kernel requires an %s CPU, ",
     82		       cpu_name(req_level));
     83		printf("but only detected an %s CPU.\n",
     84		       cpu_name(cpu_level));
     85		return -1;
     86	}
     87
     88	if (err_flags) {
     89		puts("This kernel requires the following features "
     90		     "not present on the CPU:\n");
     91		show_cap_strs(err_flags);
     92		putchar('\n');
     93		return -1;
     94	} else if (check_knl_erratum()) {
     95		return -1;
     96	} else {
     97		return 0;
     98	}
     99}