[PATCH v4 02/16] x86/cache: get cache size/leaves and setup cache cpumap for Dhyana

2018-08-19 Thread Pu Wen
Hygon Dhyana processor has the topology extensions bit in CPUID.
With this bit kernel can get the cache info. So add support
in cpuid4_cache_lookup_regs() to get the correct cache size.

Dhyana also find num_cache_leaves via CPUID leaf 0x801d, so
add Hygon support in find_num_cache_leaves().

Also add cacheinfo_hygon_init_llc_id() and init_hygon_cacheinfo()
functions to initialize Dhyana cache info. Setup cache cpumap in
the same way as AMD does.

Signed-off-by: Pu Wen 
---
 arch/x86/include/asm/cacheinfo.h |  1 +
 arch/x86/kernel/cpu/cacheinfo.c  | 31 +--
 arch/x86/kernel/cpu/cpu.h|  1 +
 arch/x86/kernel/cpu/hygon.c  |  3 +++
 4 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/arch/x86/include/asm/cacheinfo.h b/arch/x86/include/asm/cacheinfo.h
index e958e28..86b63c7 100644
--- a/arch/x86/include/asm/cacheinfo.h
+++ b/arch/x86/include/asm/cacheinfo.h
@@ -3,5 +3,6 @@
 #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);
 
 #endif /* _ASM_X86_CACHEINFO_H */
diff --git a/arch/x86/kernel/cpu/cacheinfo.c b/arch/x86/kernel/cpu/cacheinfo.c
index 0c5fcbd..dc1b934 100644
--- a/arch/x86/kernel/cpu/cacheinfo.c
+++ b/arch/x86/kernel/cpu/cacheinfo.c
@@ -602,6 +602,10 @@ cpuid4_cache_lookup_regs(int index, struct 
_cpuid4_info_regs *this_leaf)
else
amd_cpuid4(index, , , );
amd_init_l3_cache(this_leaf, index);
+   } else if (boot_cpu_data.x86_vendor == X86_VENDOR_HYGON) {
+   cpuid_count(0x801d, index, ,
+   , , );
+   amd_init_l3_cache(this_leaf, index);
} else {
cpuid_count(4, index, , , , );
}
@@ -625,7 +629,8 @@ static int find_num_cache_leaves(struct cpuinfo_x86 *c)
union _cpuid4_leaf_eax  cache_eax;
int i = -1;
 
-   if (c->x86_vendor == X86_VENDOR_AMD)
+   if (c->x86_vendor == X86_VENDOR_AMD ||
+   c->x86_vendor == X86_VENDOR_HYGON)
op = 0x801d;
else
op = 4;
@@ -678,6 +683,22 @@ 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)
+{
+   /*
+* We may have multiple LLCs if L3 caches exist, so check if we
+* have an L3 cache by looking at the L3 cache CPUID leaf.
+*/
+   if (!cpuid_edx(0x8006))
+   return;
+
+   /*
+* LLC is at the core complex level.
+* Core complex ID is ApicId[3] for these processors.
+*/
+   per_cpu(cpu_llc_id, cpu) = c->apicid >> 3;
+}
+
 void init_amd_cacheinfo(struct cpuinfo_x86 *c)
 {
 
@@ -691,6 +712,11 @@ void init_amd_cacheinfo(struct cpuinfo_x86 *c)
}
 }
 
+void init_hygon_cacheinfo(struct cpuinfo_x86 *c)
+{
+   num_cache_leaves = find_num_cache_leaves(c);
+}
+
 void init_intel_cacheinfo(struct cpuinfo_x86 *c)
 {
/* Cache sizes */
@@ -913,7 +939,8 @@ static void __cache_cpumap_setup(unsigned int cpu, int 
index,
int index_msb, i;
struct cpuinfo_x86 *c = _data(cpu);
 
-   if (c->x86_vendor == X86_VENDOR_AMD) {
+   if (c->x86_vendor == X86_VENDOR_AMD ||
+   c->x86_vendor == X86_VENDOR_HYGON) {
if (__cache_amd_cpumap_setup(cpu, index, base))
return;
}
diff --git a/arch/x86/kernel/cpu/cpu.h b/arch/x86/kernel/cpu/cpu.h
index 7b229af..da5446a 100644
--- a/arch/x86/kernel/cpu/cpu.h
+++ b/arch/x86/kernel/cpu/cpu.h
@@ -54,6 +54,7 @@ extern u32 get_scattered_cpuid_leaf(unsigned int level,
enum cpuid_regs_idx reg);
 extern void init_intel_cacheinfo(struct cpuinfo_x86 *c);
 extern void init_amd_cacheinfo(struct cpuinfo_x86 *c);
+extern void init_hygon_cacheinfo(struct cpuinfo_x86 *c);
 
 extern void detect_num_cpu_cores(struct cpuinfo_x86 *c);
 extern int detect_extended_topology_early(struct cpuinfo_x86 *c);
diff --git a/arch/x86/kernel/cpu/hygon.c b/arch/x86/kernel/cpu/hygon.c
index 50bdce5..4e6d64e 100644
--- a/arch/x86/kernel/cpu/hygon.c
+++ b/arch/x86/kernel/cpu/hygon.c
@@ -90,6 +90,7 @@ static void hygon_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);
} else if (cpu_has(c, X86_FEATURE_NODEID_MSR)) {
u64 value;
 
@@ -320,6 +321,8 @@ static void init_hygon(struct cpuinfo_x86 *c)
hygon_get_topology(c);
srat_detect_node(c);
 
+   init_hygon_cacheinfo(c);
+
set_cpu_cap(c, X86_FEATURE_K8);
 
if (cpu_has(c, X86_FEATURE_XMM2)) {
-- 
2.7.4



[PATCH v4 02/16] x86/cache: get cache size/leaves and setup cache cpumap for Dhyana

2018-08-19 Thread Pu Wen
Hygon Dhyana processor has the topology extensions bit in CPUID.
With this bit kernel can get the cache info. So add support
in cpuid4_cache_lookup_regs() to get the correct cache size.

Dhyana also find num_cache_leaves via CPUID leaf 0x801d, so
add Hygon support in find_num_cache_leaves().

Also add cacheinfo_hygon_init_llc_id() and init_hygon_cacheinfo()
functions to initialize Dhyana cache info. Setup cache cpumap in
the same way as AMD does.

Signed-off-by: Pu Wen 
---
 arch/x86/include/asm/cacheinfo.h |  1 +
 arch/x86/kernel/cpu/cacheinfo.c  | 31 +--
 arch/x86/kernel/cpu/cpu.h|  1 +
 arch/x86/kernel/cpu/hygon.c  |  3 +++
 4 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/arch/x86/include/asm/cacheinfo.h b/arch/x86/include/asm/cacheinfo.h
index e958e28..86b63c7 100644
--- a/arch/x86/include/asm/cacheinfo.h
+++ b/arch/x86/include/asm/cacheinfo.h
@@ -3,5 +3,6 @@
 #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);
 
 #endif /* _ASM_X86_CACHEINFO_H */
diff --git a/arch/x86/kernel/cpu/cacheinfo.c b/arch/x86/kernel/cpu/cacheinfo.c
index 0c5fcbd..dc1b934 100644
--- a/arch/x86/kernel/cpu/cacheinfo.c
+++ b/arch/x86/kernel/cpu/cacheinfo.c
@@ -602,6 +602,10 @@ cpuid4_cache_lookup_regs(int index, struct 
_cpuid4_info_regs *this_leaf)
else
amd_cpuid4(index, , , );
amd_init_l3_cache(this_leaf, index);
+   } else if (boot_cpu_data.x86_vendor == X86_VENDOR_HYGON) {
+   cpuid_count(0x801d, index, ,
+   , , );
+   amd_init_l3_cache(this_leaf, index);
} else {
cpuid_count(4, index, , , , );
}
@@ -625,7 +629,8 @@ static int find_num_cache_leaves(struct cpuinfo_x86 *c)
union _cpuid4_leaf_eax  cache_eax;
int i = -1;
 
-   if (c->x86_vendor == X86_VENDOR_AMD)
+   if (c->x86_vendor == X86_VENDOR_AMD ||
+   c->x86_vendor == X86_VENDOR_HYGON)
op = 0x801d;
else
op = 4;
@@ -678,6 +683,22 @@ 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)
+{
+   /*
+* We may have multiple LLCs if L3 caches exist, so check if we
+* have an L3 cache by looking at the L3 cache CPUID leaf.
+*/
+   if (!cpuid_edx(0x8006))
+   return;
+
+   /*
+* LLC is at the core complex level.
+* Core complex ID is ApicId[3] for these processors.
+*/
+   per_cpu(cpu_llc_id, cpu) = c->apicid >> 3;
+}
+
 void init_amd_cacheinfo(struct cpuinfo_x86 *c)
 {
 
@@ -691,6 +712,11 @@ void init_amd_cacheinfo(struct cpuinfo_x86 *c)
}
 }
 
+void init_hygon_cacheinfo(struct cpuinfo_x86 *c)
+{
+   num_cache_leaves = find_num_cache_leaves(c);
+}
+
 void init_intel_cacheinfo(struct cpuinfo_x86 *c)
 {
/* Cache sizes */
@@ -913,7 +939,8 @@ static void __cache_cpumap_setup(unsigned int cpu, int 
index,
int index_msb, i;
struct cpuinfo_x86 *c = _data(cpu);
 
-   if (c->x86_vendor == X86_VENDOR_AMD) {
+   if (c->x86_vendor == X86_VENDOR_AMD ||
+   c->x86_vendor == X86_VENDOR_HYGON) {
if (__cache_amd_cpumap_setup(cpu, index, base))
return;
}
diff --git a/arch/x86/kernel/cpu/cpu.h b/arch/x86/kernel/cpu/cpu.h
index 7b229af..da5446a 100644
--- a/arch/x86/kernel/cpu/cpu.h
+++ b/arch/x86/kernel/cpu/cpu.h
@@ -54,6 +54,7 @@ extern u32 get_scattered_cpuid_leaf(unsigned int level,
enum cpuid_regs_idx reg);
 extern void init_intel_cacheinfo(struct cpuinfo_x86 *c);
 extern void init_amd_cacheinfo(struct cpuinfo_x86 *c);
+extern void init_hygon_cacheinfo(struct cpuinfo_x86 *c);
 
 extern void detect_num_cpu_cores(struct cpuinfo_x86 *c);
 extern int detect_extended_topology_early(struct cpuinfo_x86 *c);
diff --git a/arch/x86/kernel/cpu/hygon.c b/arch/x86/kernel/cpu/hygon.c
index 50bdce5..4e6d64e 100644
--- a/arch/x86/kernel/cpu/hygon.c
+++ b/arch/x86/kernel/cpu/hygon.c
@@ -90,6 +90,7 @@ static void hygon_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);
} else if (cpu_has(c, X86_FEATURE_NODEID_MSR)) {
u64 value;
 
@@ -320,6 +321,8 @@ static void init_hygon(struct cpuinfo_x86 *c)
hygon_get_topology(c);
srat_detect_node(c);
 
+   init_hygon_cacheinfo(c);
+
set_cpu_cap(c, X86_FEATURE_K8);
 
if (cpu_has(c, X86_FEATURE_XMM2)) {
-- 
2.7.4