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

intel_pconfig.c (1939B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Intel PCONFIG instruction support.
      4 *
      5 * Copyright (C) 2017 Intel Corporation
      6 *
      7 * Author:
      8 *	Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
      9 */
     10
     11#include <asm/cpufeature.h>
     12#include <asm/intel_pconfig.h>
     13
     14#define	PCONFIG_CPUID			0x1b
     15
     16#define PCONFIG_CPUID_SUBLEAF_MASK	((1 << 12) - 1)
     17
     18/* Subleaf type (EAX) for PCONFIG CPUID leaf (0x1B) */
     19enum {
     20	PCONFIG_CPUID_SUBLEAF_INVALID	= 0,
     21	PCONFIG_CPUID_SUBLEAF_TARGETID	= 1,
     22};
     23
     24/* Bitmask of supported targets */
     25static u64 targets_supported __read_mostly;
     26
     27int pconfig_target_supported(enum pconfig_target target)
     28{
     29	/*
     30	 * We would need to re-think the implementation once we get > 64
     31	 * PCONFIG targets. Spec allows up to 2^32 targets.
     32	 */
     33	BUILD_BUG_ON(PCONFIG_TARGET_NR >= 64);
     34
     35	if (WARN_ON_ONCE(target >= 64))
     36		return 0;
     37	return targets_supported & (1ULL << target);
     38}
     39
     40static int __init intel_pconfig_init(void)
     41{
     42	int subleaf;
     43
     44	if (!boot_cpu_has(X86_FEATURE_PCONFIG))
     45		return 0;
     46
     47	/*
     48	 * Scan subleafs of PCONFIG CPUID leaf.
     49	 *
     50	 * Subleafs of the same type need not to be consecutive.
     51	 *
     52	 * Stop on the first invalid subleaf type. All subleafs after the first
     53	 * invalid are invalid too.
     54	 */
     55	for (subleaf = 0; subleaf < INT_MAX; subleaf++) {
     56		struct cpuid_regs regs;
     57
     58		cpuid_count(PCONFIG_CPUID, subleaf,
     59				&regs.eax, &regs.ebx, &regs.ecx, &regs.edx);
     60
     61		switch (regs.eax & PCONFIG_CPUID_SUBLEAF_MASK) {
     62		case PCONFIG_CPUID_SUBLEAF_INVALID:
     63			/* Stop on the first invalid subleaf */
     64			goto out;
     65		case PCONFIG_CPUID_SUBLEAF_TARGETID:
     66			/* Mark supported PCONFIG targets */
     67			if (regs.ebx < 64)
     68				targets_supported |= (1ULL << regs.ebx);
     69			if (regs.ecx < 64)
     70				targets_supported |= (1ULL << regs.ecx);
     71			if (regs.edx < 64)
     72				targets_supported |= (1ULL << regs.edx);
     73			break;
     74		default:
     75			/* Unknown CPUID.PCONFIG subleaf: ignore */
     76			break;
     77		}
     78	}
     79out:
     80	return 0;
     81}
     82arch_initcall(intel_pconfig_init);