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.
|
||||
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
|
||||
Description: human-readable list of CPUs within the same die.
|
||||
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/thread_siblings
|
||||
/sys/devices/system/cpu/cpuX/topology/thread_siblings_list
|
||||
/sys/devices/system/cpu/cpuX/topology/ppin
|
||||
Date: December 2008
|
||||
Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org>
|
||||
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
|
||||
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.
|
||||
|
||||
|
||||
|
@ -299,9 +299,6 @@
|
||||
/* 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_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 */
|
||||
#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_ARCH_LBR (18*32+19) /* Intel ARCH LBR */
|
||||
#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_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_INTEL_STIBP (18*32+27) /* "" Single Thread Indirect Branch Predictors */
|
||||
#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_power;
|
||||
unsigned long loops_per_jiffy;
|
||||
/* protected processor identification number */
|
||||
u64 ppin;
|
||||
/* cpuid returned max cores value: */
|
||||
u16 x86_max_cores;
|
||||
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_die_id(cpu) (cpu_data(cpu).cpu_die_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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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.
|
||||
* If BIOS has not enabled SME then don't advertise the
|
||||
* 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
|
||||
* 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))
|
||||
goto clear_all;
|
||||
|
||||
if (!sme_me_mask)
|
||||
setup_clear_cpu_cap(X86_FEATURE_SME);
|
||||
|
||||
rdmsrl(MSR_K7_HWCR, msr);
|
||||
if (!(msr & MSR_K7_HWCR_SMMLOCK))
|
||||
goto clear_sev;
|
||||
@ -947,7 +923,6 @@ static void init_amd(struct cpuinfo_x86 *c)
|
||||
amd_detect_cmp(c);
|
||||
amd_get_topology(c);
|
||||
srat_detect_node(c);
|
||||
amd_detect_ppin(c);
|
||||
|
||||
init_amd_cacheinfo(c);
|
||||
|
||||
|
@ -89,6 +89,83 @@ EXPORT_SYMBOL_GPL(get_llc_id);
|
||||
/* L2 cache ID of each logical CPU */
|
||||
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 */
|
||||
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];
|
||||
}
|
||||
|
||||
ppin_init(c);
|
||||
|
||||
/* Init Machine Check Exception if available. */
|
||||
mcheck_cpu_init(c);
|
||||
|
||||
|
@ -993,6 +993,7 @@ static struct attribute *default_attrs[] = {
|
||||
NULL, /* possibly interrupt_enable if supported, see below */
|
||||
NULL,
|
||||
};
|
||||
ATTRIBUTE_GROUPS(default);
|
||||
|
||||
#define to_block(k) container_of(k, struct threshold_block, kobj)
|
||||
#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 = {
|
||||
.sysfs_ops = &threshold_ops,
|
||||
.default_attrs = default_attrs,
|
||||
.default_groups = default_groups,
|
||||
.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;
|
||||
|
||||
if (b->interrupt_capable) {
|
||||
threshold_ktype.default_attrs[2] = &interrupt_enable.attr;
|
||||
default_attrs[2] = &interrupt_enable.attr;
|
||||
b->interrupt_enable = 1;
|
||||
} else {
|
||||
threshold_ktype.default_attrs[2] = NULL;
|
||||
default_attrs[2] = NULL;
|
||||
}
|
||||
|
||||
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->apicid = cpu_data(m->extcpu).initial_apicid;
|
||||
m->mcgcap = __rdmsr(MSR_IA32_MCG_CAP);
|
||||
|
||||
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->ppin = cpu_data(m->extcpu).ppin;
|
||||
m->microcode = boot_cpu_data.microcode;
|
||||
}
|
||||
|
||||
|
@ -470,47 +470,6 @@ void intel_clear_lmce(void)
|
||||
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
|
||||
* 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_lmce();
|
||||
intel_ppin_init(c);
|
||||
intel_imc_init(c);
|
||||
}
|
||||
|
||||
|
@ -26,6 +26,7 @@ struct cpuid_bit {
|
||||
static const struct cpuid_bit cpuid_bits[] = {
|
||||
{ X86_FEATURE_APERFMPERF, CPUID_ECX, 0, 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_OCCUP_LLC, CPUID_EDX, 0, 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
|
||||
* and potentially end up with the wrong entry being committed to
|
||||
* 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();
|
||||
for (;;) {
|
||||
/*
|
||||
|
@ -14,11 +14,11 @@
|
||||
#include <linux/hardirq.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, \
|
||||
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) \
|
||||
@ -42,22 +42,25 @@ static ssize_t name##_list_read(struct file *file, struct kobject *kobj, \
|
||||
off, count); \
|
||||
}
|
||||
|
||||
define_id_show_func(physical_package_id);
|
||||
define_id_show_func(physical_package_id, "%d");
|
||||
static DEVICE_ATTR_RO(physical_package_id);
|
||||
|
||||
#ifdef TOPOLOGY_DIE_SYSFS
|
||||
define_id_show_func(die_id);
|
||||
define_id_show_func(die_id, "%d");
|
||||
static DEVICE_ATTR_RO(die_id);
|
||||
#endif
|
||||
|
||||
#ifdef TOPOLOGY_CLUSTER_SYSFS
|
||||
define_id_show_func(cluster_id);
|
||||
define_id_show_func(cluster_id, "%d");
|
||||
static DEVICE_ATTR_RO(cluster_id);
|
||||
#endif
|
||||
|
||||
define_id_show_func(core_id);
|
||||
define_id_show_func(core_id, "%d");
|
||||
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);
|
||||
static BIN_ATTR_RO(thread_siblings, 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);
|
||||
|
||||
#ifdef TOPOLOGY_BOOK_SYSFS
|
||||
define_id_show_func(book_id);
|
||||
define_id_show_func(book_id, "%d");
|
||||
static DEVICE_ATTR_RO(book_id);
|
||||
define_siblings_read_func(book_siblings, book_cpumask);
|
||||
static BIN_ATTR_RO(book_siblings, 0);
|
||||
@ -95,7 +98,7 @@ static BIN_ATTR_RO(book_siblings_list, 0);
|
||||
#endif
|
||||
|
||||
#ifdef TOPOLOGY_DRAWER_SYSFS
|
||||
define_id_show_func(drawer_id);
|
||||
define_id_show_func(drawer_id, "%d");
|
||||
static DEVICE_ATTR_RO(drawer_id);
|
||||
define_siblings_read_func(drawer_siblings, drawer_cpumask);
|
||||
static BIN_ATTR_RO(drawer_siblings, 0);
|
||||
@ -145,6 +148,7 @@ static struct attribute *default_attrs[] = {
|
||||
#ifdef TOPOLOGY_DRAWER_SYSFS
|
||||
&dev_attr_drawer_id.attr,
|
||||
#endif
|
||||
&dev_attr_ppin.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -211,6 +211,9 @@ static inline int cpu_to_mem(int cpu)
|
||||
#ifndef topology_drawer_id
|
||||
#define topology_drawer_id(cpu) ((void)(cpu), -1)
|
||||
#endif
|
||||
#ifndef topology_ppin
|
||||
#define topology_ppin(cpu) ((void)(cpu), 0ull)
|
||||
#endif
|
||||
#ifndef topology_sibling_cpumask
|
||||
#define topology_sibling_cpumask(cpu) cpumask_of(cpu)
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user