From e9b41930355f4cd8f9f6377c2e2376839158b99b Mon Sep 17 00:00:00 2001 From: leoliu-oc Date: Mon, 11 Mar 2024 17:11:02 +0800 Subject: [PATCH 1/3] x86/cpufeatures: Add low performance CRC32C instruction CPU feature SSE4.2 on Zhaoxin CPUs are compatible with Intel. The presence of CRC32C instruction is enumerated by CPUID.01H:ECX.SSE4_2[bit 20] = 1. Some Zhaoxin CPUs declare support SSE4.2 instruction sets but their CRC32C instruction are working with low performance. Add a synthetic CPU flag to indicates that the CRC32C instruction is not working as intended. This low performance CRC32C instruction flag is depend on X86_FEATURE_XMM4_2. Signed-off-by: leoliu-oc --- arch/x86/include/asm/cpufeatures.h | 1 + arch/x86/kernel/cpu/cpuid-deps.c | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h index 8b0c0399e85a..2a9a4e9b7610 100644 --- a/arch/x86/include/asm/cpufeatures.h +++ b/arch/x86/include/asm/cpufeatures.h @@ -331,6 +331,7 @@ #define X86_FEATURE_SRSO_ALIAS (11*32+25) /* "" AMD BTB untrain RETs through aliasing */ #define X86_FEATURE_IBPB_ON_VMEXIT (11*32+26) /* "" Issue an IBPB only on VMEXIT */ #define X86_FEATURE_APIC_MSRS_FENCE (11*32+27) /* "" IA32_TSC_DEADLINE and X2APIC MSRs need fencing */ +#define X86_FEATURE_CRC32C_LOW_PERF (11*32+28) /* "" Low performance */ /* Intel-defined CPU features, CPUID level 0x00000007:1 (EAX), word 12 */ #define X86_FEATURE_AVX_VNNI (12*32+ 4) /* AVX VNNI instructions */ diff --git a/arch/x86/kernel/cpu/cpuid-deps.c b/arch/x86/kernel/cpu/cpuid-deps.c index e462c1d3800a..4f559eb49525 100644 --- a/arch/x86/kernel/cpu/cpuid-deps.c +++ b/arch/x86/kernel/cpu/cpuid-deps.c @@ -82,6 +82,7 @@ static const struct cpuid_dep cpuid_deps[] = { { X86_FEATURE_XFD, X86_FEATURE_XGETBV1 }, { X86_FEATURE_AMX_TILE, X86_FEATURE_XFD }, { X86_FEATURE_SHSTK, X86_FEATURE_XSAVES }, + { X86_FEATURE_CRC32C_LOW_PERF, X86_FEATURE_XMM4_2 }, {} }; -- Gitee From c3818f3513dece1bf04710531193054e232665a0 Mon Sep 17 00:00:00 2001 From: leoliu-oc Date: Fri, 15 Mar 2024 10:56:45 +0800 Subject: [PATCH 2/3] x86/cpu: Set low performance CRC32C flag on some Zhaoxin CPUs Some Zhaoxin CPUs declare support SSE4.2 instruction sets but having a CRC32C instruction implementation that not working as intended. Set low performance CRC32C flag on these CPUs for later use. Signed-off-by: leoliu-oc --- arch/x86/kernel/cpu/centaur.c | 7 +++++++ arch/x86/kernel/cpu/zhaoxin.c | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/arch/x86/kernel/cpu/centaur.c b/arch/x86/kernel/cpu/centaur.c index a5c01c8f8824..ad6982391bc9 100644 --- a/arch/x86/kernel/cpu/centaur.c +++ b/arch/x86/kernel/cpu/centaur.c @@ -110,6 +110,13 @@ static void early_init_centaur(struct cpuinfo_x86 *c) set_cpu_cap(c, X86_FEATURE_NONSTOP_TSC); } + /* + * These CPUs declare support SSE4.2 instruction sets but + * having low performance CRC32C instruction implementation. + */ + if (c->x86 == 0x6 || (c->x86 == 0x7 && c->x86_model <= 0x3b)) + set_cpu_cap(c, X86_FEATURE_CRC32C_LOW_PERF); + if (detect_extended_topology_early(c) < 0) detect_ht_early(c); } diff --git a/arch/x86/kernel/cpu/zhaoxin.c b/arch/x86/kernel/cpu/zhaoxin.c index 2126b10de796..f9a65b57a6bd 100644 --- a/arch/x86/kernel/cpu/zhaoxin.c +++ b/arch/x86/kernel/cpu/zhaoxin.c @@ -79,6 +79,13 @@ static void early_init_zhaoxin(struct cpuinfo_x86 *c) c->x86_coreid_bits = get_count_order((ebx >> 16) & 0xff); } + /* + * These CPUs declare support SSE4.2 instruction sets but + * having low performance CRC32C instruction implementation. + */ + if (c->x86 == 0x6 || (c->x86 == 0x7 && c->x86_model <= 0x3b)) + set_cpu_cap(c, X86_FEATURE_CRC32C_LOW_PERF); + if (detect_extended_topology_early(c) < 0) detect_ht_early(c); } -- Gitee From 464c248ffcd5f5a2faa140953ed33c4fe623c551 Mon Sep 17 00:00:00 2001 From: leoliu-oc Date: Wed, 27 Dec 2023 21:04:57 +0800 Subject: [PATCH 3/3] crypto: x86/crc32c-intel Exclude low performance CRC32C instruction CPUs Low performance CRC32C instruction CPUs expect to use the driver crc32c-generic. So remove these CPUs support from crc32c-intel. Signed-off-by: leoliu-oc --- arch/x86/crypto/crc32c-intel_glue.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/x86/crypto/crc32c-intel_glue.c b/arch/x86/crypto/crc32c-intel_glue.c index feccb5254c7e..91d318b08fb7 100644 --- a/arch/x86/crypto/crc32c-intel_glue.c +++ b/arch/x86/crypto/crc32c-intel_glue.c @@ -224,6 +224,11 @@ static int __init crc32c_intel_mod_init(void) { if (!x86_match_cpu(crc32c_cpu_id)) return -ENODEV; + + /* Don't merit use low performance CRC32C instruction */ + if (boot_cpu_has(X86_FEATURE_CRC32C_LOW_PERF)) + return -ENODEV; + #ifdef CONFIG_X86_64 if (boot_cpu_has(X86_FEATURE_PCLMULQDQ)) { alg.update = crc32c_pcl_intel_update; -- Gitee