Merge branch 'x86/cpu' into x86/core, to resolve conflicts
Conflicts: arch/x86/include/asm/cpufeatures.h Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
commit
9cea0d46f5
|
@ -86,6 +86,10 @@ What: /sys/devices/system/cpu/cpuX/topology/die_cpus
|
||||||
Description: internal kernel map of CPUs within the same die.
|
Description: internal kernel map of CPUs within the same die.
|
||||||
Values: hexadecimal bitmask.
|
Values: hexadecimal bitmask.
|
||||||
|
|
||||||
|
What: /sys/devices/system/cpu/cpuX/topology/ppin
|
||||||
|
Description: per-socket protected processor inventory number
|
||||||
|
Values: hexadecimal.
|
||||||
|
|
||||||
What: /sys/devices/system/cpu/cpuX/topology/die_cpus_list
|
What: /sys/devices/system/cpu/cpuX/topology/die_cpus_list
|
||||||
Description: human-readable list of CPUs within the same die.
|
Description: human-readable list of CPUs within the same die.
|
||||||
The format is like 0-3, 8-11, 14,17.
|
The format is like 0-3, 8-11, 14,17.
|
||||||
|
|
|
@ -73,6 +73,7 @@ What: /sys/devices/system/cpu/cpuX/topology/core_id
|
||||||
/sys/devices/system/cpu/cpuX/topology/physical_package_id
|
/sys/devices/system/cpu/cpuX/topology/physical_package_id
|
||||||
/sys/devices/system/cpu/cpuX/topology/thread_siblings
|
/sys/devices/system/cpu/cpuX/topology/thread_siblings
|
||||||
/sys/devices/system/cpu/cpuX/topology/thread_siblings_list
|
/sys/devices/system/cpu/cpuX/topology/thread_siblings_list
|
||||||
|
/sys/devices/system/cpu/cpuX/topology/ppin
|
||||||
Date: December 2008
|
Date: December 2008
|
||||||
Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org>
|
Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org>
|
||||||
Description: CPU topology files that describe a logical CPU's relationship
|
Description: CPU topology files that describe a logical CPU's relationship
|
||||||
|
@ -103,6 +104,11 @@ Description: CPU topology files that describe a logical CPU's relationship
|
||||||
thread_siblings_list: human-readable list of cpuX's hardware
|
thread_siblings_list: human-readable list of cpuX's hardware
|
||||||
threads within the same core as cpuX
|
threads within the same core as cpuX
|
||||||
|
|
||||||
|
ppin: human-readable Protected Processor Identification
|
||||||
|
Number of the socket the cpu# belongs to. There should be
|
||||||
|
one per physical_package_id. File is readable only to
|
||||||
|
admin.
|
||||||
|
|
||||||
See Documentation/admin-guide/cputopology.rst for more information.
|
See Documentation/admin-guide/cputopology.rst for more information.
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -299,9 +299,6 @@
|
||||||
/* Intel-defined CPU features, CPUID level 0x00000007:1 (EAX), word 12 */
|
/* Intel-defined CPU features, CPUID level 0x00000007:1 (EAX), word 12 */
|
||||||
#define X86_FEATURE_AVX_VNNI (12*32+ 4) /* AVX VNNI instructions */
|
#define X86_FEATURE_AVX_VNNI (12*32+ 4) /* AVX VNNI instructions */
|
||||||
#define X86_FEATURE_AVX512_BF16 (12*32+ 5) /* AVX512 BFLOAT16 instructions */
|
#define X86_FEATURE_AVX512_BF16 (12*32+ 5) /* AVX512 BFLOAT16 instructions */
|
||||||
#define X86_FEATURE_AMX_BF16 (18*32+22) /* AMX bf16 Support */
|
|
||||||
#define X86_FEATURE_AMX_TILE (18*32+24) /* AMX tile Support */
|
|
||||||
#define X86_FEATURE_AMX_INT8 (18*32+25) /* AMX int8 Support */
|
|
||||||
|
|
||||||
/* AMD-defined CPU features, CPUID level 0x80000008 (EBX), word 13 */
|
/* AMD-defined CPU features, CPUID level 0x80000008 (EBX), word 13 */
|
||||||
#define X86_FEATURE_CLZERO (13*32+ 0) /* CLZERO instruction */
|
#define X86_FEATURE_CLZERO (13*32+ 0) /* CLZERO instruction */
|
||||||
|
@ -391,7 +388,10 @@
|
||||||
#define X86_FEATURE_PCONFIG (18*32+18) /* Intel PCONFIG */
|
#define X86_FEATURE_PCONFIG (18*32+18) /* Intel PCONFIG */
|
||||||
#define X86_FEATURE_ARCH_LBR (18*32+19) /* Intel ARCH LBR */
|
#define X86_FEATURE_ARCH_LBR (18*32+19) /* Intel ARCH LBR */
|
||||||
#define X86_FEATURE_IBT (18*32+20) /* Indirect Branch Tracking */
|
#define X86_FEATURE_IBT (18*32+20) /* Indirect Branch Tracking */
|
||||||
|
#define X86_FEATURE_AMX_BF16 (18*32+22) /* AMX bf16 Support */
|
||||||
#define X86_FEATURE_AVX512_FP16 (18*32+23) /* AVX512 FP16 */
|
#define X86_FEATURE_AVX512_FP16 (18*32+23) /* AVX512 FP16 */
|
||||||
|
#define X86_FEATURE_AMX_TILE (18*32+24) /* AMX tile Support */
|
||||||
|
#define X86_FEATURE_AMX_INT8 (18*32+25) /* AMX int8 Support */
|
||||||
#define X86_FEATURE_SPEC_CTRL (18*32+26) /* "" Speculation Control (IBRS + IBPB) */
|
#define X86_FEATURE_SPEC_CTRL (18*32+26) /* "" Speculation Control (IBRS + IBPB) */
|
||||||
#define X86_FEATURE_INTEL_STIBP (18*32+27) /* "" Single Thread Indirect Branch Predictors */
|
#define X86_FEATURE_INTEL_STIBP (18*32+27) /* "" Single Thread Indirect Branch Predictors */
|
||||||
#define X86_FEATURE_FLUSH_L1D (18*32+28) /* Flush L1D cache */
|
#define X86_FEATURE_FLUSH_L1D (18*32+28) /* Flush L1D cache */
|
||||||
|
|
|
@ -119,6 +119,8 @@ struct cpuinfo_x86 {
|
||||||
int x86_cache_mbm_width_offset;
|
int x86_cache_mbm_width_offset;
|
||||||
int x86_power;
|
int x86_power;
|
||||||
unsigned long loops_per_jiffy;
|
unsigned long loops_per_jiffy;
|
||||||
|
/* protected processor identification number */
|
||||||
|
u64 ppin;
|
||||||
/* cpuid returned max cores value: */
|
/* cpuid returned max cores value: */
|
||||||
u16 x86_max_cores;
|
u16 x86_max_cores;
|
||||||
u16 apicid;
|
u16 apicid;
|
||||||
|
|
|
@ -110,6 +110,7 @@ extern const struct cpumask *cpu_clustergroup_mask(int cpu);
|
||||||
#define topology_logical_die_id(cpu) (cpu_data(cpu).logical_die_id)
|
#define topology_logical_die_id(cpu) (cpu_data(cpu).logical_die_id)
|
||||||
#define topology_die_id(cpu) (cpu_data(cpu).cpu_die_id)
|
#define topology_die_id(cpu) (cpu_data(cpu).cpu_die_id)
|
||||||
#define topology_core_id(cpu) (cpu_data(cpu).cpu_core_id)
|
#define topology_core_id(cpu) (cpu_data(cpu).cpu_core_id)
|
||||||
|
#define topology_ppin(cpu) (cpu_data(cpu).ppin)
|
||||||
|
|
||||||
extern unsigned int __max_die_per_package;
|
extern unsigned int __max_die_per_package;
|
||||||
|
|
||||||
|
|
|
@ -394,35 +394,6 @@ static void amd_detect_cmp(struct cpuinfo_x86 *c)
|
||||||
per_cpu(cpu_llc_id, cpu) = c->cpu_die_id = c->phys_proc_id;
|
per_cpu(cpu_llc_id, cpu) = c->cpu_die_id = c->phys_proc_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void amd_detect_ppin(struct cpuinfo_x86 *c)
|
|
||||||
{
|
|
||||||
unsigned long long val;
|
|
||||||
|
|
||||||
if (!cpu_has(c, X86_FEATURE_AMD_PPIN))
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* When PPIN is defined in CPUID, still need to check PPIN_CTL MSR */
|
|
||||||
if (rdmsrl_safe(MSR_AMD_PPIN_CTL, &val))
|
|
||||||
goto clear_ppin;
|
|
||||||
|
|
||||||
/* PPIN is locked in disabled mode, clear feature bit */
|
|
||||||
if ((val & 3UL) == 1UL)
|
|
||||||
goto clear_ppin;
|
|
||||||
|
|
||||||
/* If PPIN is disabled, try to enable it */
|
|
||||||
if (!(val & 2UL)) {
|
|
||||||
wrmsrl_safe(MSR_AMD_PPIN_CTL, val | 2UL);
|
|
||||||
rdmsrl_safe(MSR_AMD_PPIN_CTL, &val);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If PPIN_EN bit is 1, return from here; otherwise fall through */
|
|
||||||
if (val & 2UL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
clear_ppin:
|
|
||||||
clear_cpu_cap(c, X86_FEATURE_AMD_PPIN);
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 amd_get_nodes_per_socket(void)
|
u32 amd_get_nodes_per_socket(void)
|
||||||
{
|
{
|
||||||
return nodes_per_socket;
|
return nodes_per_socket;
|
||||||
|
@ -585,6 +556,8 @@ static void early_detect_mem_encrypt(struct cpuinfo_x86 *c)
|
||||||
* the SME physical address space reduction value.
|
* the SME physical address space reduction value.
|
||||||
* If BIOS has not enabled SME then don't advertise the
|
* If BIOS has not enabled SME then don't advertise the
|
||||||
* SME feature (set in scattered.c).
|
* SME feature (set in scattered.c).
|
||||||
|
* If the kernel has not enabled SME via any means then
|
||||||
|
* don't advertise the SME feature.
|
||||||
* For SEV: If BIOS has not enabled SEV then don't advertise the
|
* For SEV: If BIOS has not enabled SEV then don't advertise the
|
||||||
* SEV and SEV_ES feature (set in scattered.c).
|
* SEV and SEV_ES feature (set in scattered.c).
|
||||||
*
|
*
|
||||||
|
@ -607,6 +580,9 @@ static void early_detect_mem_encrypt(struct cpuinfo_x86 *c)
|
||||||
if (IS_ENABLED(CONFIG_X86_32))
|
if (IS_ENABLED(CONFIG_X86_32))
|
||||||
goto clear_all;
|
goto clear_all;
|
||||||
|
|
||||||
|
if (!sme_me_mask)
|
||||||
|
setup_clear_cpu_cap(X86_FEATURE_SME);
|
||||||
|
|
||||||
rdmsrl(MSR_K7_HWCR, msr);
|
rdmsrl(MSR_K7_HWCR, msr);
|
||||||
if (!(msr & MSR_K7_HWCR_SMMLOCK))
|
if (!(msr & MSR_K7_HWCR_SMMLOCK))
|
||||||
goto clear_sev;
|
goto clear_sev;
|
||||||
|
@ -947,7 +923,6 @@ static void init_amd(struct cpuinfo_x86 *c)
|
||||||
amd_detect_cmp(c);
|
amd_detect_cmp(c);
|
||||||
amd_get_topology(c);
|
amd_get_topology(c);
|
||||||
srat_detect_node(c);
|
srat_detect_node(c);
|
||||||
amd_detect_ppin(c);
|
|
||||||
|
|
||||||
init_amd_cacheinfo(c);
|
init_amd_cacheinfo(c);
|
||||||
|
|
||||||
|
|
|
@ -89,6 +89,83 @@ EXPORT_SYMBOL_GPL(get_llc_id);
|
||||||
/* L2 cache ID of each logical CPU */
|
/* L2 cache ID of each logical CPU */
|
||||||
DEFINE_PER_CPU_READ_MOSTLY(u16, cpu_l2c_id) = BAD_APICID;
|
DEFINE_PER_CPU_READ_MOSTLY(u16, cpu_l2c_id) = BAD_APICID;
|
||||||
|
|
||||||
|
static struct ppin_info {
|
||||||
|
int feature;
|
||||||
|
int msr_ppin_ctl;
|
||||||
|
int msr_ppin;
|
||||||
|
} ppin_info[] = {
|
||||||
|
[X86_VENDOR_INTEL] = {
|
||||||
|
.feature = X86_FEATURE_INTEL_PPIN,
|
||||||
|
.msr_ppin_ctl = MSR_PPIN_CTL,
|
||||||
|
.msr_ppin = MSR_PPIN
|
||||||
|
},
|
||||||
|
[X86_VENDOR_AMD] = {
|
||||||
|
.feature = X86_FEATURE_AMD_PPIN,
|
||||||
|
.msr_ppin_ctl = MSR_AMD_PPIN_CTL,
|
||||||
|
.msr_ppin = MSR_AMD_PPIN
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct x86_cpu_id ppin_cpuids[] = {
|
||||||
|
X86_MATCH_FEATURE(X86_FEATURE_AMD_PPIN, &ppin_info[X86_VENDOR_AMD]),
|
||||||
|
X86_MATCH_FEATURE(X86_FEATURE_INTEL_PPIN, &ppin_info[X86_VENDOR_INTEL]),
|
||||||
|
|
||||||
|
/* Legacy models without CPUID enumeration */
|
||||||
|
X86_MATCH_INTEL_FAM6_MODEL(IVYBRIDGE_X, &ppin_info[X86_VENDOR_INTEL]),
|
||||||
|
X86_MATCH_INTEL_FAM6_MODEL(HASWELL_X, &ppin_info[X86_VENDOR_INTEL]),
|
||||||
|
X86_MATCH_INTEL_FAM6_MODEL(BROADWELL_D, &ppin_info[X86_VENDOR_INTEL]),
|
||||||
|
X86_MATCH_INTEL_FAM6_MODEL(BROADWELL_X, &ppin_info[X86_VENDOR_INTEL]),
|
||||||
|
X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE_X, &ppin_info[X86_VENDOR_INTEL]),
|
||||||
|
X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_X, &ppin_info[X86_VENDOR_INTEL]),
|
||||||
|
X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_D, &ppin_info[X86_VENDOR_INTEL]),
|
||||||
|
X86_MATCH_INTEL_FAM6_MODEL(SAPPHIRERAPIDS_X, &ppin_info[X86_VENDOR_INTEL]),
|
||||||
|
X86_MATCH_INTEL_FAM6_MODEL(XEON_PHI_KNL, &ppin_info[X86_VENDOR_INTEL]),
|
||||||
|
X86_MATCH_INTEL_FAM6_MODEL(XEON_PHI_KNM, &ppin_info[X86_VENDOR_INTEL]),
|
||||||
|
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
static void ppin_init(struct cpuinfo_x86 *c)
|
||||||
|
{
|
||||||
|
const struct x86_cpu_id *id;
|
||||||
|
unsigned long long val;
|
||||||
|
struct ppin_info *info;
|
||||||
|
|
||||||
|
id = x86_match_cpu(ppin_cpuids);
|
||||||
|
if (!id)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Testing the presence of the MSR is not enough. Need to check
|
||||||
|
* that the PPIN_CTL allows reading of the PPIN.
|
||||||
|
*/
|
||||||
|
info = (struct ppin_info *)id->driver_data;
|
||||||
|
|
||||||
|
if (rdmsrl_safe(info->msr_ppin_ctl, &val))
|
||||||
|
goto clear_ppin;
|
||||||
|
|
||||||
|
if ((val & 3UL) == 1UL) {
|
||||||
|
/* PPIN locked in disabled mode */
|
||||||
|
goto clear_ppin;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If PPIN is disabled, try to enable */
|
||||||
|
if (!(val & 2UL)) {
|
||||||
|
wrmsrl_safe(info->msr_ppin_ctl, val | 2UL);
|
||||||
|
rdmsrl_safe(info->msr_ppin_ctl, &val);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Is the enable bit set? */
|
||||||
|
if (val & 2UL) {
|
||||||
|
c->ppin = __rdmsr(info->msr_ppin);
|
||||||
|
set_cpu_cap(c, info->feature);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
clear_ppin:
|
||||||
|
clear_cpu_cap(c, info->feature);
|
||||||
|
}
|
||||||
|
|
||||||
/* correctly size the local cpu masks */
|
/* correctly size the local cpu masks */
|
||||||
void __init setup_cpu_local_masks(void)
|
void __init setup_cpu_local_masks(void)
|
||||||
{
|
{
|
||||||
|
@ -1710,6 +1787,8 @@ static void identify_cpu(struct cpuinfo_x86 *c)
|
||||||
c->x86_capability[i] |= boot_cpu_data.x86_capability[i];
|
c->x86_capability[i] |= boot_cpu_data.x86_capability[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ppin_init(c);
|
||||||
|
|
||||||
/* Init Machine Check Exception if available. */
|
/* Init Machine Check Exception if available. */
|
||||||
mcheck_cpu_init(c);
|
mcheck_cpu_init(c);
|
||||||
|
|
||||||
|
|
|
@ -993,6 +993,7 @@ static struct attribute *default_attrs[] = {
|
||||||
NULL, /* possibly interrupt_enable if supported, see below */
|
NULL, /* possibly interrupt_enable if supported, see below */
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
ATTRIBUTE_GROUPS(default);
|
||||||
|
|
||||||
#define to_block(k) container_of(k, struct threshold_block, kobj)
|
#define to_block(k) container_of(k, struct threshold_block, kobj)
|
||||||
#define to_attr(a) container_of(a, struct threshold_attr, attr)
|
#define to_attr(a) container_of(a, struct threshold_attr, attr)
|
||||||
|
@ -1029,7 +1030,7 @@ static void threshold_block_release(struct kobject *kobj);
|
||||||
|
|
||||||
static struct kobj_type threshold_ktype = {
|
static struct kobj_type threshold_ktype = {
|
||||||
.sysfs_ops = &threshold_ops,
|
.sysfs_ops = &threshold_ops,
|
||||||
.default_attrs = default_attrs,
|
.default_groups = default_groups,
|
||||||
.release = threshold_block_release,
|
.release = threshold_block_release,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1101,10 +1102,10 @@ static int allocate_threshold_blocks(unsigned int cpu, struct threshold_bank *tb
|
||||||
b->threshold_limit = THRESHOLD_MAX;
|
b->threshold_limit = THRESHOLD_MAX;
|
||||||
|
|
||||||
if (b->interrupt_capable) {
|
if (b->interrupt_capable) {
|
||||||
threshold_ktype.default_attrs[2] = &interrupt_enable.attr;
|
default_attrs[2] = &interrupt_enable.attr;
|
||||||
b->interrupt_enable = 1;
|
b->interrupt_enable = 1;
|
||||||
} else {
|
} else {
|
||||||
threshold_ktype.default_attrs[2] = NULL;
|
default_attrs[2] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
INIT_LIST_HEAD(&b->miscj);
|
INIT_LIST_HEAD(&b->miscj);
|
||||||
|
|
|
@ -138,12 +138,7 @@ void mce_setup(struct mce *m)
|
||||||
m->socketid = cpu_data(m->extcpu).phys_proc_id;
|
m->socketid = cpu_data(m->extcpu).phys_proc_id;
|
||||||
m->apicid = cpu_data(m->extcpu).initial_apicid;
|
m->apicid = cpu_data(m->extcpu).initial_apicid;
|
||||||
m->mcgcap = __rdmsr(MSR_IA32_MCG_CAP);
|
m->mcgcap = __rdmsr(MSR_IA32_MCG_CAP);
|
||||||
|
m->ppin = cpu_data(m->extcpu).ppin;
|
||||||
if (this_cpu_has(X86_FEATURE_INTEL_PPIN))
|
|
||||||
m->ppin = __rdmsr(MSR_PPIN);
|
|
||||||
else if (this_cpu_has(X86_FEATURE_AMD_PPIN))
|
|
||||||
m->ppin = __rdmsr(MSR_AMD_PPIN);
|
|
||||||
|
|
||||||
m->microcode = boot_cpu_data.microcode;
|
m->microcode = boot_cpu_data.microcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -470,47 +470,6 @@ void intel_clear_lmce(void)
|
||||||
wrmsrl(MSR_IA32_MCG_EXT_CTL, val);
|
wrmsrl(MSR_IA32_MCG_EXT_CTL, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void intel_ppin_init(struct cpuinfo_x86 *c)
|
|
||||||
{
|
|
||||||
unsigned long long val;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Even if testing the presence of the MSR would be enough, we don't
|
|
||||||
* want to risk the situation where other models reuse this MSR for
|
|
||||||
* other purposes.
|
|
||||||
*/
|
|
||||||
switch (c->x86_model) {
|
|
||||||
case INTEL_FAM6_IVYBRIDGE_X:
|
|
||||||
case INTEL_FAM6_HASWELL_X:
|
|
||||||
case INTEL_FAM6_BROADWELL_D:
|
|
||||||
case INTEL_FAM6_BROADWELL_X:
|
|
||||||
case INTEL_FAM6_SKYLAKE_X:
|
|
||||||
case INTEL_FAM6_ICELAKE_X:
|
|
||||||
case INTEL_FAM6_ICELAKE_D:
|
|
||||||
case INTEL_FAM6_SAPPHIRERAPIDS_X:
|
|
||||||
case INTEL_FAM6_XEON_PHI_KNL:
|
|
||||||
case INTEL_FAM6_XEON_PHI_KNM:
|
|
||||||
|
|
||||||
if (rdmsrl_safe(MSR_PPIN_CTL, &val))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if ((val & 3UL) == 1UL) {
|
|
||||||
/* PPIN locked in disabled mode */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If PPIN is disabled, try to enable */
|
|
||||||
if (!(val & 2UL)) {
|
|
||||||
wrmsrl_safe(MSR_PPIN_CTL, val | 2UL);
|
|
||||||
rdmsrl_safe(MSR_PPIN_CTL, &val);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Is the enable bit set? */
|
|
||||||
if (val & 2UL)
|
|
||||||
set_cpu_cap(c, X86_FEATURE_INTEL_PPIN);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Enable additional error logs from the integrated
|
* Enable additional error logs from the integrated
|
||||||
* memory controller on processors that support this.
|
* memory controller on processors that support this.
|
||||||
|
@ -535,7 +494,6 @@ void mce_intel_feature_init(struct cpuinfo_x86 *c)
|
||||||
{
|
{
|
||||||
intel_init_cmci();
|
intel_init_cmci();
|
||||||
intel_init_lmce();
|
intel_init_lmce();
|
||||||
intel_ppin_init(c);
|
|
||||||
intel_imc_init(c);
|
intel_imc_init(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@ struct cpuid_bit {
|
||||||
static const struct cpuid_bit cpuid_bits[] = {
|
static const struct cpuid_bit cpuid_bits[] = {
|
||||||
{ X86_FEATURE_APERFMPERF, CPUID_ECX, 0, 0x00000006, 0 },
|
{ X86_FEATURE_APERFMPERF, CPUID_ECX, 0, 0x00000006, 0 },
|
||||||
{ X86_FEATURE_EPB, CPUID_ECX, 3, 0x00000006, 0 },
|
{ X86_FEATURE_EPB, CPUID_ECX, 3, 0x00000006, 0 },
|
||||||
|
{ X86_FEATURE_INTEL_PPIN, CPUID_EBX, 0, 0x00000007, 1 },
|
||||||
{ X86_FEATURE_CQM_LLC, CPUID_EDX, 1, 0x0000000f, 0 },
|
{ X86_FEATURE_CQM_LLC, CPUID_EDX, 1, 0x0000000f, 0 },
|
||||||
{ X86_FEATURE_CQM_OCCUP_LLC, CPUID_EDX, 0, 0x0000000f, 1 },
|
{ X86_FEATURE_CQM_OCCUP_LLC, CPUID_EDX, 0, 0x0000000f, 1 },
|
||||||
{ X86_FEATURE_CQM_MBM_TOTAL, CPUID_EDX, 1, 0x0000000f, 1 },
|
{ X86_FEATURE_CQM_MBM_TOTAL, CPUID_EDX, 1, 0x0000000f, 1 },
|
||||||
|
|
|
@ -765,8 +765,11 @@ void __noreturn stop_this_cpu(void *dummy)
|
||||||
* without the encryption bit, they don't race each other when flushed
|
* without the encryption bit, they don't race each other when flushed
|
||||||
* and potentially end up with the wrong entry being committed to
|
* and potentially end up with the wrong entry being committed to
|
||||||
* memory.
|
* memory.
|
||||||
|
*
|
||||||
|
* Test the CPUID bit directly because the machine might've cleared
|
||||||
|
* X86_FEATURE_SME due to cmdline options.
|
||||||
*/
|
*/
|
||||||
if (boot_cpu_has(X86_FEATURE_SME))
|
if (cpuid_eax(0x8000001f) & BIT(0))
|
||||||
native_wbinvd();
|
native_wbinvd();
|
||||||
for (;;) {
|
for (;;) {
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -14,11 +14,11 @@
|
||||||
#include <linux/hardirq.h>
|
#include <linux/hardirq.h>
|
||||||
#include <linux/topology.h>
|
#include <linux/topology.h>
|
||||||
|
|
||||||
#define define_id_show_func(name) \
|
#define define_id_show_func(name, fmt) \
|
||||||
static ssize_t name##_show(struct device *dev, \
|
static ssize_t name##_show(struct device *dev, \
|
||||||
struct device_attribute *attr, char *buf) \
|
struct device_attribute *attr, char *buf) \
|
||||||
{ \
|
{ \
|
||||||
return sysfs_emit(buf, "%d\n", topology_##name(dev->id)); \
|
return sysfs_emit(buf, fmt "\n", topology_##name(dev->id)); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define define_siblings_read_func(name, mask) \
|
#define define_siblings_read_func(name, mask) \
|
||||||
|
@ -42,22 +42,25 @@ static ssize_t name##_list_read(struct file *file, struct kobject *kobj, \
|
||||||
off, count); \
|
off, count); \
|
||||||
}
|
}
|
||||||
|
|
||||||
define_id_show_func(physical_package_id);
|
define_id_show_func(physical_package_id, "%d");
|
||||||
static DEVICE_ATTR_RO(physical_package_id);
|
static DEVICE_ATTR_RO(physical_package_id);
|
||||||
|
|
||||||
#ifdef TOPOLOGY_DIE_SYSFS
|
#ifdef TOPOLOGY_DIE_SYSFS
|
||||||
define_id_show_func(die_id);
|
define_id_show_func(die_id, "%d");
|
||||||
static DEVICE_ATTR_RO(die_id);
|
static DEVICE_ATTR_RO(die_id);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef TOPOLOGY_CLUSTER_SYSFS
|
#ifdef TOPOLOGY_CLUSTER_SYSFS
|
||||||
define_id_show_func(cluster_id);
|
define_id_show_func(cluster_id, "%d");
|
||||||
static DEVICE_ATTR_RO(cluster_id);
|
static DEVICE_ATTR_RO(cluster_id);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
define_id_show_func(core_id);
|
define_id_show_func(core_id, "%d");
|
||||||
static DEVICE_ATTR_RO(core_id);
|
static DEVICE_ATTR_RO(core_id);
|
||||||
|
|
||||||
|
define_id_show_func(ppin, "0x%llx");
|
||||||
|
static DEVICE_ATTR_ADMIN_RO(ppin);
|
||||||
|
|
||||||
define_siblings_read_func(thread_siblings, sibling_cpumask);
|
define_siblings_read_func(thread_siblings, sibling_cpumask);
|
||||||
static BIN_ATTR_RO(thread_siblings, 0);
|
static BIN_ATTR_RO(thread_siblings, 0);
|
||||||
static BIN_ATTR_RO(thread_siblings_list, 0);
|
static BIN_ATTR_RO(thread_siblings_list, 0);
|
||||||
|
@ -87,7 +90,7 @@ static BIN_ATTR_RO(package_cpus, 0);
|
||||||
static BIN_ATTR_RO(package_cpus_list, 0);
|
static BIN_ATTR_RO(package_cpus_list, 0);
|
||||||
|
|
||||||
#ifdef TOPOLOGY_BOOK_SYSFS
|
#ifdef TOPOLOGY_BOOK_SYSFS
|
||||||
define_id_show_func(book_id);
|
define_id_show_func(book_id, "%d");
|
||||||
static DEVICE_ATTR_RO(book_id);
|
static DEVICE_ATTR_RO(book_id);
|
||||||
define_siblings_read_func(book_siblings, book_cpumask);
|
define_siblings_read_func(book_siblings, book_cpumask);
|
||||||
static BIN_ATTR_RO(book_siblings, 0);
|
static BIN_ATTR_RO(book_siblings, 0);
|
||||||
|
@ -95,7 +98,7 @@ static BIN_ATTR_RO(book_siblings_list, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef TOPOLOGY_DRAWER_SYSFS
|
#ifdef TOPOLOGY_DRAWER_SYSFS
|
||||||
define_id_show_func(drawer_id);
|
define_id_show_func(drawer_id, "%d");
|
||||||
static DEVICE_ATTR_RO(drawer_id);
|
static DEVICE_ATTR_RO(drawer_id);
|
||||||
define_siblings_read_func(drawer_siblings, drawer_cpumask);
|
define_siblings_read_func(drawer_siblings, drawer_cpumask);
|
||||||
static BIN_ATTR_RO(drawer_siblings, 0);
|
static BIN_ATTR_RO(drawer_siblings, 0);
|
||||||
|
@ -145,6 +148,7 @@ static struct attribute *default_attrs[] = {
|
||||||
#ifdef TOPOLOGY_DRAWER_SYSFS
|
#ifdef TOPOLOGY_DRAWER_SYSFS
|
||||||
&dev_attr_drawer_id.attr,
|
&dev_attr_drawer_id.attr,
|
||||||
#endif
|
#endif
|
||||||
|
&dev_attr_ppin.attr,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -211,6 +211,9 @@ static inline int cpu_to_mem(int cpu)
|
||||||
#ifndef topology_drawer_id
|
#ifndef topology_drawer_id
|
||||||
#define topology_drawer_id(cpu) ((void)(cpu), -1)
|
#define topology_drawer_id(cpu) ((void)(cpu), -1)
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef topology_ppin
|
||||||
|
#define topology_ppin(cpu) ((void)(cpu), 0ull)
|
||||||
|
#endif
|
||||||
#ifndef topology_sibling_cpumask
|
#ifndef topology_sibling_cpumask
|
||||||
#define topology_sibling_cpumask(cpu) cpumask_of(cpu)
|
#define topology_sibling_cpumask(cpu) cpumask_of(cpu)
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue