From 06325190bd577e11429444d54f454b9d13f560c9 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Thu, 27 Feb 2014 08:47:02 +0000 Subject: x86, hash: Fix build failure with older binutils Just like for other ISA extension instruction uses we should check whether the assembler actually supports them. The fallback here simply is to encode an instruction with fixed operands (%eax and %ecx). [ hpa: tagging for -stable as a build fix ] Signed-off-by: Jan Beulich Link: http://lkml.kernel.org/r/530F0996020000780011FBE7@nat28.tlf.novell.com Cc: Francesco Fusco Cc: Thomas Graf Cc: David S. Miller Acked-by: Daniel Borkmann Signed-off-by: H. Peter Anvin Cc: # v3.14 diff --git a/arch/x86/Makefile b/arch/x86/Makefile index eeda43a..f8842c4 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -152,6 +152,7 @@ cfi-sections := $(call as-instr,.cfi_sections .debug_frame,-DCONFIG_AS_CFI_SECTI # does binutils support specific instructions? asinstr := $(call as-instr,fxsaveq (%rax),-DCONFIG_AS_FXSAVEQ=1) +asinstr += $(call as-instr,crc32l %eax$(comma)%eax,-DCONFIG_AS_CRC32=1) avx_instr := $(call as-instr,vxorps %ymm0$(comma)%ymm1$(comma)%ymm2,-DCONFIG_AS_AVX=1) avx2_instr :=$(call as-instr,vpbroadcastb %xmm0$(comma)%ymm1,-DCONFIG_AS_AVX2=1) diff --git a/arch/x86/lib/hash.c b/arch/x86/lib/hash.c index 3056702..060cc44 100644 --- a/arch/x86/lib/hash.c +++ b/arch/x86/lib/hash.c @@ -39,7 +39,11 @@ static inline u32 crc32_u32(u32 crc, u32 val) { +#ifdef CONFIG_AS_CRC32 asm ("crc32l %1,%0\n" : "+r" (crc) : "rm" (val)); +#else + asm (".byte 0xf2, 0x0f, 0x38, 0xf1, 0xc1" : "+a" (crc) : "c" (val)); +#endif return crc; } -- cgit v0.10.2 From c5cdfdf90901c51363441365997eecd58efd9374 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Thu, 27 Feb 2014 08:47:34 +0000 Subject: x86, hash: Swap arguments passed to crc32_u32() ... to match the function's parameters. While reportedly commutative, using the proper order allows for leveraging the instruction permitting the source operand to be in memory. [ hpa: This code originated in the dpdk toolkit. This was a bug in dpdk which has recently been fixed in part due to an earlier version of this patch. ] Signed-off-by: Jan Beulich Link: http://lkml.kernel.org/r/530F09B6020000780011FBEB@nat28.tlf.novell.com Acked-by: Daniel Borkmann Cc: Francesco Fusco Cc: Thomas Graf Cc: David S. Miller Signed-off-by: H. Peter Anvin diff --git a/arch/x86/lib/hash.c b/arch/x86/lib/hash.c index 060cc44..ac628aa 100644 --- a/arch/x86/lib/hash.c +++ b/arch/x86/lib/hash.c @@ -53,7 +53,7 @@ static u32 intel_crc4_2_hash(const void *data, u32 len, u32 seed) u32 i, tmp = 0; for (i = 0; i < len / 4; i++) - seed = crc32_u32(*p32++, seed); + seed = crc32_u32(seed, *p32++); switch (3 - (len & 0x03)) { case 0: @@ -64,7 +64,7 @@ static u32 intel_crc4_2_hash(const void *data, u32 len, u32 seed) /* fallthrough */ case 2: tmp |= *((const u8 *) p32); - seed = crc32_u32(tmp, seed); + seed = crc32_u32(seed, tmp); default: break; } @@ -78,7 +78,7 @@ static u32 intel_crc4_2_hash2(const u32 *data, u32 len, u32 seed) u32 i; for (i = 0; i < len; i++) - seed = crc32_u32(*p32++, seed); + seed = crc32_u32(seed, *p32++); return seed; } -- cgit v0.10.2 From 7a5917e9787dd73284f04e35c3cfdb39a67bf0d5 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Thu, 27 Feb 2014 08:47:58 +0000 Subject: x86, hash: Simplify switch, add __init annotation Minor cleanups: - simplify switch statement - add __init annotation to setup_arch_fast_hash() Signed-off-by: Jan Beulich Link: http://lkml.kernel.org/r/530F09CE020000780011FBEF@nat28.tlf.novell.com Cc: Francesco Fusco Cc: Thomas Graf Cc: David S. Miller Acked-by: Daniel Borkmann Signed-off-by: H. Peter Anvin diff --git a/arch/x86/lib/hash.c b/arch/x86/lib/hash.c index ac628aa..ff4fa51 100644 --- a/arch/x86/lib/hash.c +++ b/arch/x86/lib/hash.c @@ -32,6 +32,7 @@ */ #include +#include #include #include @@ -55,17 +56,16 @@ static u32 intel_crc4_2_hash(const void *data, u32 len, u32 seed) for (i = 0; i < len / 4; i++) seed = crc32_u32(seed, *p32++); - switch (3 - (len & 0x03)) { - case 0: + switch (len & 3) { + case 3: tmp |= *((const u8 *) p32 + 2) << 16; /* fallthrough */ - case 1: + case 2: tmp |= *((const u8 *) p32 + 1) << 8; /* fallthrough */ - case 2: + case 1: tmp |= *((const u8 *) p32); seed = crc32_u32(seed, tmp); - default: break; } @@ -83,7 +83,7 @@ static u32 intel_crc4_2_hash2(const u32 *data, u32 len, u32 seed) return seed; } -void setup_arch_fast_hash(struct fast_hash_ops *ops) +void __init setup_arch_fast_hash(struct fast_hash_ops *ops) { if (cpu_has_xmm4_2) { ops->hash = intel_crc4_2_hash; -- cgit v0.10.2