Commit 028c221e authored by Yazen Ghannam's avatar Yazen Ghannam Committed by Borislav Petkov

x86/CPU/AMD: Save AMD NodeId as cpu_die_id

AMD systems provide a "NodeId" value that represents a global ID
indicating to which "Node" a logical CPU belongs. The "Node" is a
physical structure equivalent to a Die, and it should not be confused
with logical structures like NUMA nodes. Logical nodes can be adjusted
based on firmware or other settings whereas the physical nodes/dies are
fixed based on hardware topology.

The NodeId value can be used when a physical ID is needed by software.

Save the AMD NodeId to struct cpuinfo_x86.cpu_die_id. Use the value
from CPUID or MSR as appropriate. Default to phys_proc_id otherwise.
Do so for both AMD and Hygon systems.

Drop the node_id parameter from cacheinfo_*_init_llc_id() as it is no
longer needed.

Update the x86 topology documentation.
Suggested-by: default avatarBorislav Petkov <bp@alien8.de>
Signed-off-by: default avatarYazen Ghannam <yazen.ghannam@amd.com>
Signed-off-by: default avatarBorislav Petkov <bp@suse.de>
Link: https://lkml.kernel.org/r/20201109210659.754018-2-Yazen.Ghannam@amd.com
parent 09162bc3
...@@ -41,6 +41,8 @@ Package ...@@ -41,6 +41,8 @@ Package
Packages contain a number of cores plus shared resources, e.g. DRAM Packages contain a number of cores plus shared resources, e.g. DRAM
controller, shared caches etc. controller, shared caches etc.
Modern systems may also use the term 'Die' for package.
AMD nomenclature for package is 'Node'. AMD nomenclature for package is 'Node'.
Package-related topology information in the kernel: Package-related topology information in the kernel:
...@@ -53,11 +55,18 @@ Package-related topology information in the kernel: ...@@ -53,11 +55,18 @@ Package-related topology information in the kernel:
The number of dies in a package. This information is retrieved via CPUID. The number of dies in a package. This information is retrieved via CPUID.
- cpuinfo_x86.cpu_die_id:
The physical ID of the die. This information is retrieved via CPUID.
- cpuinfo_x86.phys_proc_id: - cpuinfo_x86.phys_proc_id:
The physical ID of the package. This information is retrieved via CPUID The physical ID of the package. This information is retrieved via CPUID
and deduced from the APIC IDs of the cores in the package. and deduced from the APIC IDs of the cores in the package.
Modern systems use this value for the socket. There may be multiple
packages within a socket. This value may differ from cpu_die_id.
- cpuinfo_x86.logical_proc_id: - cpuinfo_x86.logical_proc_id:
The logical ID of the package. As we do not trust BIOSes to enumerate the The logical ID of the package. As we do not trust BIOSes to enumerate the
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
#ifndef _ASM_X86_CACHEINFO_H #ifndef _ASM_X86_CACHEINFO_H
#define _ASM_X86_CACHEINFO_H #define _ASM_X86_CACHEINFO_H
void cacheinfo_amd_init_llc_id(struct cpuinfo_x86 *c, int cpu, u8 node_id); void cacheinfo_amd_init_llc_id(struct cpuinfo_x86 *c, int cpu);
void cacheinfo_hygon_init_llc_id(struct cpuinfo_x86 *c, int cpu, u8 node_id); void cacheinfo_hygon_init_llc_id(struct cpuinfo_x86 *c, int cpu);
#endif /* _ASM_X86_CACHEINFO_H */ #endif /* _ASM_X86_CACHEINFO_H */
...@@ -330,7 +330,6 @@ static void legacy_fixup_core_id(struct cpuinfo_x86 *c) ...@@ -330,7 +330,6 @@ static void legacy_fixup_core_id(struct cpuinfo_x86 *c)
*/ */
static void amd_get_topology(struct cpuinfo_x86 *c) static void amd_get_topology(struct cpuinfo_x86 *c)
{ {
u8 node_id;
int cpu = smp_processor_id(); int cpu = smp_processor_id();
/* get information required for multi-node processors */ /* get information required for multi-node processors */
...@@ -340,7 +339,7 @@ static void amd_get_topology(struct cpuinfo_x86 *c) ...@@ -340,7 +339,7 @@ static void amd_get_topology(struct cpuinfo_x86 *c)
cpuid(0x8000001e, &eax, &ebx, &ecx, &edx); cpuid(0x8000001e, &eax, &ebx, &ecx, &edx);
node_id = ecx & 0xff; c->cpu_die_id = ecx & 0xff;
if (c->x86 == 0x15) if (c->x86 == 0x15)
c->cu_id = ebx & 0xff; c->cu_id = ebx & 0xff;
...@@ -360,15 +359,15 @@ static void amd_get_topology(struct cpuinfo_x86 *c) ...@@ -360,15 +359,15 @@ static void amd_get_topology(struct cpuinfo_x86 *c)
if (!err) if (!err)
c->x86_coreid_bits = get_count_order(c->x86_max_cores); c->x86_coreid_bits = get_count_order(c->x86_max_cores);
cacheinfo_amd_init_llc_id(c, cpu, node_id); cacheinfo_amd_init_llc_id(c, cpu);
} else if (cpu_has(c, X86_FEATURE_NODEID_MSR)) { } else if (cpu_has(c, X86_FEATURE_NODEID_MSR)) {
u64 value; u64 value;
rdmsrl(MSR_FAM10H_NODE_ID, value); rdmsrl(MSR_FAM10H_NODE_ID, value);
node_id = value & 7; c->cpu_die_id = value & 7;
per_cpu(cpu_llc_id, cpu) = node_id; per_cpu(cpu_llc_id, cpu) = c->cpu_die_id;
} else } else
return; return;
...@@ -393,7 +392,7 @@ static void amd_detect_cmp(struct cpuinfo_x86 *c) ...@@ -393,7 +392,7 @@ static void amd_detect_cmp(struct cpuinfo_x86 *c)
/* Convert the initial APIC ID into the socket ID */ /* Convert the initial APIC ID into the socket ID */
c->phys_proc_id = c->initial_apicid >> bits; c->phys_proc_id = c->initial_apicid >> bits;
/* use socket ID also for last level cache */ /* use socket ID also for last level cache */
per_cpu(cpu_llc_id, cpu) = 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) static void amd_detect_ppin(struct cpuinfo_x86 *c)
......
...@@ -646,7 +646,7 @@ static int find_num_cache_leaves(struct cpuinfo_x86 *c) ...@@ -646,7 +646,7 @@ static int find_num_cache_leaves(struct cpuinfo_x86 *c)
return i; return i;
} }
void cacheinfo_amd_init_llc_id(struct cpuinfo_x86 *c, int cpu, u8 node_id) void cacheinfo_amd_init_llc_id(struct cpuinfo_x86 *c, int cpu)
{ {
/* /*
* We may have multiple LLCs if L3 caches exist, so check if we * We may have multiple LLCs if L3 caches exist, so check if we
...@@ -657,7 +657,7 @@ void cacheinfo_amd_init_llc_id(struct cpuinfo_x86 *c, int cpu, u8 node_id) ...@@ -657,7 +657,7 @@ void cacheinfo_amd_init_llc_id(struct cpuinfo_x86 *c, int cpu, u8 node_id)
if (c->x86 < 0x17) { if (c->x86 < 0x17) {
/* LLC is at the node level. */ /* LLC is at the node level. */
per_cpu(cpu_llc_id, cpu) = node_id; per_cpu(cpu_llc_id, cpu) = c->cpu_die_id;
} else if (c->x86 == 0x17 && c->x86_model <= 0x1F) { } else if (c->x86 == 0x17 && c->x86_model <= 0x1F) {
/* /*
* LLC is at the core complex level. * LLC is at the core complex level.
...@@ -684,7 +684,7 @@ void cacheinfo_amd_init_llc_id(struct cpuinfo_x86 *c, int cpu, u8 node_id) ...@@ -684,7 +684,7 @@ void cacheinfo_amd_init_llc_id(struct cpuinfo_x86 *c, int cpu, u8 node_id)
} }
} }
void cacheinfo_hygon_init_llc_id(struct cpuinfo_x86 *c, int cpu, u8 node_id) void cacheinfo_hygon_init_llc_id(struct cpuinfo_x86 *c, int cpu)
{ {
/* /*
* We may have multiple LLCs if L3 caches exist, so check if we * We may have multiple LLCs if L3 caches exist, so check if we
......
...@@ -65,7 +65,6 @@ static void hygon_get_topology_early(struct cpuinfo_x86 *c) ...@@ -65,7 +65,6 @@ static void hygon_get_topology_early(struct cpuinfo_x86 *c)
*/ */
static void hygon_get_topology(struct cpuinfo_x86 *c) static void hygon_get_topology(struct cpuinfo_x86 *c)
{ {
u8 node_id;
int cpu = smp_processor_id(); int cpu = smp_processor_id();
/* get information required for multi-node processors */ /* get information required for multi-node processors */
...@@ -75,7 +74,7 @@ static void hygon_get_topology(struct cpuinfo_x86 *c) ...@@ -75,7 +74,7 @@ static void hygon_get_topology(struct cpuinfo_x86 *c)
cpuid(0x8000001e, &eax, &ebx, &ecx, &edx); cpuid(0x8000001e, &eax, &ebx, &ecx, &edx);
node_id = ecx & 0xff; c->cpu_die_id = ecx & 0xff;
c->cpu_core_id = ebx & 0xff; c->cpu_core_id = ebx & 0xff;
...@@ -93,14 +92,14 @@ static void hygon_get_topology(struct cpuinfo_x86 *c) ...@@ -93,14 +92,14 @@ static void hygon_get_topology(struct cpuinfo_x86 *c)
/* Socket ID is ApicId[6] for these processors. */ /* Socket ID is ApicId[6] for these processors. */
c->phys_proc_id = c->apicid >> APICID_SOCKET_ID_BIT; c->phys_proc_id = c->apicid >> APICID_SOCKET_ID_BIT;
cacheinfo_hygon_init_llc_id(c, cpu, node_id); cacheinfo_hygon_init_llc_id(c, cpu);
} else if (cpu_has(c, X86_FEATURE_NODEID_MSR)) { } else if (cpu_has(c, X86_FEATURE_NODEID_MSR)) {
u64 value; u64 value;
rdmsrl(MSR_FAM10H_NODE_ID, value); rdmsrl(MSR_FAM10H_NODE_ID, value);
node_id = value & 7; c->cpu_die_id = value & 7;
per_cpu(cpu_llc_id, cpu) = node_id; per_cpu(cpu_llc_id, cpu) = c->cpu_die_id;
} else } else
return; return;
...@@ -123,7 +122,7 @@ static void hygon_detect_cmp(struct cpuinfo_x86 *c) ...@@ -123,7 +122,7 @@ static void hygon_detect_cmp(struct cpuinfo_x86 *c)
/* Convert the initial APIC ID into the socket ID */ /* Convert the initial APIC ID into the socket ID */
c->phys_proc_id = c->initial_apicid >> bits; c->phys_proc_id = c->initial_apicid >> bits;
/* use socket ID also for last level cache */ /* use socket ID also for last level cache */
per_cpu(cpu_llc_id, cpu) = c->phys_proc_id; per_cpu(cpu_llc_id, cpu) = c->cpu_die_id = c->phys_proc_id;
} }
static void srat_detect_node(struct cpuinfo_x86 *c) static void srat_detect_node(struct cpuinfo_x86 *c)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment