aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKirill A. Shutemov <kirill.shutemov@linux.intel.com>2018-03-05 11:25:52 -0500
committerIngo Molnar <mingo@kernel.org>2018-03-12 07:10:54 -0400
commitbe7825c19b4866ddc7b1431740b69ede2eeb93c1 (patch)
tree50745124ec8ec6087abc90df7a790ac68060c7d1
parentcb06d8e3d020c30fe10ae711c925a5319ab82c88 (diff)
x86/pconfig: Detect PCONFIG targets
Intel PCONFIG targets are enumerated via new CPUID leaf 0x1b. This patch detects all supported targets of PCONFIG and implements helper to check if the target is supported. Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> Cc: Dave Hansen <dave.hansen@intel.com> Cc: Kai Huang <kai.huang@linux.intel.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Tom Lendacky <thomas.lendacky@amd.com> Cc: linux-mm@kvack.org Link: http://lkml.kernel.org/r/20180305162610.37510-5-kirill.shutemov@linux.intel.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--arch/x86/include/asm/intel_pconfig.h15
-rw-r--r--arch/x86/kernel/cpu/Makefile2
-rw-r--r--arch/x86/kernel/cpu/intel_pconfig.c82
3 files changed, 98 insertions, 1 deletions
diff --git a/arch/x86/include/asm/intel_pconfig.h b/arch/x86/include/asm/intel_pconfig.h
new file mode 100644
index 000000000000..fb7a37c3798b
--- /dev/null
+++ b/arch/x86/include/asm/intel_pconfig.h
@@ -0,0 +1,15 @@
1#ifndef _ASM_X86_INTEL_PCONFIG_H
2#define _ASM_X86_INTEL_PCONFIG_H
3
4#include <asm/asm.h>
5#include <asm/processor.h>
6
7enum pconfig_target {
8 INVALID_TARGET = 0,
9 MKTME_TARGET = 1,
10 PCONFIG_TARGET_NR
11};
12
13int pconfig_target_supported(enum pconfig_target target);
14
15#endif /* _ASM_X86_INTEL_PCONFIG_H */
diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile
index 570e8bb1f386..a66229f51b12 100644
--- a/arch/x86/kernel/cpu/Makefile
+++ b/arch/x86/kernel/cpu/Makefile
@@ -28,7 +28,7 @@ obj-y += cpuid-deps.o
28obj-$(CONFIG_PROC_FS) += proc.o 28obj-$(CONFIG_PROC_FS) += proc.o
29obj-$(CONFIG_X86_FEATURE_NAMES) += capflags.o powerflags.o 29obj-$(CONFIG_X86_FEATURE_NAMES) += capflags.o powerflags.o
30 30
31obj-$(CONFIG_CPU_SUP_INTEL) += intel.o 31obj-$(CONFIG_CPU_SUP_INTEL) += intel.o intel_pconfig.o
32obj-$(CONFIG_CPU_SUP_AMD) += amd.o 32obj-$(CONFIG_CPU_SUP_AMD) += amd.o
33obj-$(CONFIG_CPU_SUP_CYRIX_32) += cyrix.o 33obj-$(CONFIG_CPU_SUP_CYRIX_32) += cyrix.o
34obj-$(CONFIG_CPU_SUP_CENTAUR) += centaur.o 34obj-$(CONFIG_CPU_SUP_CENTAUR) += centaur.o
diff --git a/arch/x86/kernel/cpu/intel_pconfig.c b/arch/x86/kernel/cpu/intel_pconfig.c
new file mode 100644
index 000000000000..0771a905b286
--- /dev/null
+++ b/arch/x86/kernel/cpu/intel_pconfig.c
@@ -0,0 +1,82 @@
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);