0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <asm/cpufeature.h>
0012 #include <asm/intel_pconfig.h>
0013
0014 #define PCONFIG_CPUID 0x1b
0015
0016 #define PCONFIG_CPUID_SUBLEAF_MASK ((1 << 12) - 1)
0017
0018
0019 enum {
0020 PCONFIG_CPUID_SUBLEAF_INVALID = 0,
0021 PCONFIG_CPUID_SUBLEAF_TARGETID = 1,
0022 };
0023
0024
0025 static u64 targets_supported __read_mostly;
0026
0027 int pconfig_target_supported(enum pconfig_target target)
0028 {
0029
0030
0031
0032
0033 BUILD_BUG_ON(PCONFIG_TARGET_NR >= 64);
0034
0035 if (WARN_ON_ONCE(target >= 64))
0036 return 0;
0037 return targets_supported & (1ULL << target);
0038 }
0039
0040 static int __init intel_pconfig_init(void)
0041 {
0042 int subleaf;
0043
0044 if (!boot_cpu_has(X86_FEATURE_PCONFIG))
0045 return 0;
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055 for (subleaf = 0; subleaf < INT_MAX; subleaf++) {
0056 struct cpuid_regs regs;
0057
0058 cpuid_count(PCONFIG_CPUID, subleaf,
0059 ®s.eax, ®s.ebx, ®s.ecx, ®s.edx);
0060
0061 switch (regs.eax & PCONFIG_CPUID_SUBLEAF_MASK) {
0062 case PCONFIG_CPUID_SUBLEAF_INVALID:
0063
0064 goto out;
0065 case PCONFIG_CPUID_SUBLEAF_TARGETID:
0066
0067 if (regs.ebx < 64)
0068 targets_supported |= (1ULL << regs.ebx);
0069 if (regs.ecx < 64)
0070 targets_supported |= (1ULL << regs.ecx);
0071 if (regs.edx < 64)
0072 targets_supported |= (1ULL << regs.edx);
0073 break;
0074 default:
0075
0076 break;
0077 }
0078 }
0079 out:
0080 return 0;
0081 }
0082 arch_initcall(intel_pconfig_init);