mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	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: Borislav Petkov <bp@alien8.de> Signed-off-by: Yazen Ghannam <yazen.ghannam@amd.com> Signed-off-by: Borislav Petkov <bp@suse.de> Link: https://lkml.kernel.org/r/20201109210659.754018-2-Yazen.Ghannam@amd.com
This commit is contained in:
		
							parent
							
								
									09162bc32c
								
							
						
					
					
						commit
						028c221ed1
					
				
					 5 changed files with 24 additions and 17 deletions
				
			
		| 
						 | 
				
			
			@ -41,6 +41,8 @@ Package
 | 
			
		|||
Packages contain a number of cores plus shared resources, e.g. DRAM
 | 
			
		||||
controller, shared caches etc.
 | 
			
		||||
 | 
			
		||||
Modern systems may also use the term 'Die' for package.
 | 
			
		||||
 | 
			
		||||
AMD nomenclature for package is 'Node'.
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
 | 
			
		||||
  - cpuinfo_x86.cpu_die_id:
 | 
			
		||||
 | 
			
		||||
    The physical ID of the die. This information is retrieved via CPUID.
 | 
			
		||||
 | 
			
		||||
  - cpuinfo_x86.phys_proc_id:
 | 
			
		||||
 | 
			
		||||
    The physical ID of the package. This information is retrieved via CPUID
 | 
			
		||||
    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:
 | 
			
		||||
 | 
			
		||||
    The logical ID of the package. As we do not trust BIOSes to enumerate the
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,7 +2,7 @@
 | 
			
		|||
#ifndef _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_hygon_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);
 | 
			
		||||
 | 
			
		||||
#endif /* _ASM_X86_CACHEINFO_H */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -330,7 +330,6 @@ static void legacy_fixup_core_id(struct cpuinfo_x86 *c)
 | 
			
		|||
 */
 | 
			
		||||
static void amd_get_topology(struct cpuinfo_x86 *c)
 | 
			
		||||
{
 | 
			
		||||
	u8 node_id;
 | 
			
		||||
	int cpu = smp_processor_id();
 | 
			
		||||
 | 
			
		||||
	/* get information required for multi-node processors */
 | 
			
		||||
| 
						 | 
				
			
			@ -340,7 +339,7 @@ static void amd_get_topology(struct cpuinfo_x86 *c)
 | 
			
		|||
 | 
			
		||||
		cpuid(0x8000001e, &eax, &ebx, &ecx, &edx);
 | 
			
		||||
 | 
			
		||||
		node_id  = ecx & 0xff;
 | 
			
		||||
		c->cpu_die_id  = ecx & 0xff;
 | 
			
		||||
 | 
			
		||||
		if (c->x86 == 0x15)
 | 
			
		||||
			c->cu_id = ebx & 0xff;
 | 
			
		||||
| 
						 | 
				
			
			@ -360,15 +359,15 @@ static void amd_get_topology(struct cpuinfo_x86 *c)
 | 
			
		|||
		if (!err)
 | 
			
		||||
			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)) {
 | 
			
		||||
		u64 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
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -393,7 +392,7 @@ static void amd_detect_cmp(struct cpuinfo_x86 *c)
 | 
			
		|||
	/* Convert the initial APIC ID into the socket ID */
 | 
			
		||||
	c->phys_proc_id = c->initial_apicid >> bits;
 | 
			
		||||
	/* 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)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -646,7 +646,7 @@ static int find_num_cache_leaves(struct cpuinfo_x86 *c)
 | 
			
		|||
	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
 | 
			
		||||
| 
						 | 
				
			
			@ -657,7 +657,7 @@ void cacheinfo_amd_init_llc_id(struct cpuinfo_x86 *c, int cpu, u8 node_id)
 | 
			
		|||
 | 
			
		||||
	if (c->x86 < 0x17) {
 | 
			
		||||
		/* 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) {
 | 
			
		||||
		/*
 | 
			
		||||
		 * 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)
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -65,7 +65,6 @@ static void hygon_get_topology_early(struct cpuinfo_x86 *c)
 | 
			
		|||
 */
 | 
			
		||||
static void hygon_get_topology(struct cpuinfo_x86 *c)
 | 
			
		||||
{
 | 
			
		||||
	u8 node_id;
 | 
			
		||||
	int cpu = smp_processor_id();
 | 
			
		||||
 | 
			
		||||
	/* get information required for multi-node processors */
 | 
			
		||||
| 
						 | 
				
			
			@ -75,7 +74,7 @@ static void hygon_get_topology(struct cpuinfo_x86 *c)
 | 
			
		|||
 | 
			
		||||
		cpuid(0x8000001e, &eax, &ebx, &ecx, &edx);
 | 
			
		||||
 | 
			
		||||
		node_id  = ecx & 0xff;
 | 
			
		||||
		c->cpu_die_id  = ecx & 0xff;
 | 
			
		||||
 | 
			
		||||
		c->cpu_core_id = ebx & 0xff;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -93,14 +92,14 @@ static void hygon_get_topology(struct cpuinfo_x86 *c)
 | 
			
		|||
		/* Socket ID is ApicId[6] for these processors. */
 | 
			
		||||
		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)) {
 | 
			
		||||
		u64 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
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -123,7 +122,7 @@ static void hygon_detect_cmp(struct cpuinfo_x86 *c)
 | 
			
		|||
	/* Convert the initial APIC ID into the socket ID */
 | 
			
		||||
	c->phys_proc_id = c->initial_apicid >> bits;
 | 
			
		||||
	/* 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)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue