Borrow the code from libgcrypt to check whether the compiler supports the assembly instructions for SSSE3, SHA extensions, SSSE4.1, AVX, AVX2, AVX512, and BMI2.
Also tweak _gcry_get_hw_features() in include/grub/crypto.h as the preparation to support the hardware feature detection function from libgcrypt. Signed-off-by: Gary Lin <g...@suse.com> --- conf/Makefile.common | 2 + configure.ac | 254 ++++++++++++++++++++++++++++++++++++++++++ include/grub/crypto.h | 4 + 3 files changed, 260 insertions(+) diff --git a/conf/Makefile.common b/conf/Makefile.common index 4d38ff034..7ef171b2b 100644 --- a/conf/Makefile.common +++ b/conf/Makefile.common @@ -24,6 +24,8 @@ if COND_HAVE_PCI CFLAGS_PLATFORM += -DGRUB_HAS_PCI endif +CPPFLAGS_GCRY_ASM = @CPPFLAGS_GCRY_ASM@ + # Other options CPPFLAGS_DEFAULT = -DGRUB_FILE=\"$(subst $(srcdir)/,,$<)\" diff --git a/configure.ac b/configure.ac index 83e3ddf90..c20b5d7c7 100644 --- a/configure.ac +++ b/configure.ac @@ -1148,6 +1148,259 @@ if test "x$grub_cv_cc_fno_ident" = xyes; then TARGET_CFLAGS="$TARGET_CFLAGS -fno-ident" fi +# Implementation of the --disable-amd64-as-feature-detection switch. +AC_MSG_CHECKING([whether to enable AMD64 as(1) feature detection]) +AC_ARG_ENABLE(amd64-as-feature-detection, + AS_HELP_STRING([--disable-amd64-as-feature-detection], + [Disable the auto-detection of AMD64 as(1) features]), + amd64_as_feature_detection=$enableval, + amd64_as_feature_detection=yes) +AC_MSG_RESULT($amd64_as_feature_detection) + +# Implementation of --disable-asm. +AC_MSG_CHECKING([whether libgcrypt assembler modules are requested]) +AC_ARG_ENABLE([asm], + AS_HELP_STRING([--disable-asm], + [Disable libgcrypt assembler modules]), + [try_asm_modules=$enableval], + [try_asm_modules=yes]) +AC_MSG_RESULT($try_asm_modules) +if test "$try_asm_modules" != yes ; then + AC_DEFINE(ASM_DISABLED,1,[Defined if --disable-asm was used to configure]) +fi + +CFLAGS_GCRY_ASM= +CPPFLAGS_GCRY_ASM= + +# +# Check whether GCC assembler supports features needed for our i386/amd64 +# implementations +# +if test $amd64_as_feature_detection = yes; then + AC_CACHE_CHECK([whether GCC assembler is compatible for i386/amd64 assembly implementations], + [gcry_cv_gcc_x86_platform_as_ok], + [if test "$target_cpu" != "x86_64" || + test "$try_asm_modules" != "yes" ; then + gcry_cv_gcc_x86_platform_as_ok="n/a" + else + gcry_cv_gcc_x86_platform_as_ok=no + AC_LINK_IFELSE([AC_LANG_PROGRAM( + [[__asm__( + /* Test if '.type' and '.size' are supported. */ + /* These work only on ELF targets. */ + ".text\n\t" + "asmfunc:\n\t" + ".size asmfunc,.-asmfunc;\n\t" + ".type asmfunc,@function;\n\t" + /* Test if assembler allows use of '/' for constant division + * (Solaris/x86 issue). If previous constant division check + * and "-Wa,--divide" workaround failed, this causes assembly + * to be disable on this machine. */ + "xorl \$(123456789/12345678), %ebp;\n\t" + ); + void asmfunc(void);]], [ asmfunc(); ])], + [gcry_cv_gcc_x86_platform_as_ok=yes]) + fi]) + if test "$gcry_cv_gcc_x86_platform_as_ok" = "yes"; then + CPPFLAGS_GCRY_ASM="-D__x86_64 -DHAVE_CPU_ARCH_X86 -DHAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS" + fi +fi + +# +# Check whether GCC assembler supports features needed for assembly +# implementations that use Intel syntax +# +AC_CACHE_CHECK([whether GCC assembler is compatible for Intel syntax assembly implementations], + [gcry_cv_gcc_platform_as_ok_for_intel_syntax], + [if test "$target_cpu" != "x86_64" || + test "$try_asm_modules" != "yes" ; then + gcry_cv_gcc_platform_as_ok_for_intel_syntax="n/a" + else + gcry_cv_gcc_platform_as_ok_for_intel_syntax=no + AC_LINK_IFELSE([AC_LANG_PROGRAM( + [[__asm__( + ".intel_syntax noprefix\n\t" + ".text\n\t" + "actest:\n\t" + "pxor xmm1, xmm7;\n\t" + "vperm2i128 ymm2, ymm3, ymm0, 1;\n\t" + "add eax, ebp;\n\t" + "rorx eax, ebp, 1;\n\t" + "sub eax, [esp + 4];\n\t" + "add dword ptr [esp + eax], 0b10101;\n\t" + ".att_syntax prefix\n\t" + ); + void actest(void);]], [ actest(); ])], + [gcry_cv_gcc_platform_as_ok_for_intel_syntax=yes]) + fi]) +if test "$gcry_cv_gcc_platform_as_ok_for_intel_syntax" = "yes" ; then + CPPFLAGS_GCRY_ASM="$CPPFLAGS_GCRY_ASM -DHAVE_INTEL_SYNTAX_PLATFORM_AS" +fi + +# +# Check whether GCC inline assembler supports SSSE3 instructions +# +AC_CACHE_CHECK([whether GCC inline assembler supports SSSE3 instructions], + [gcry_cv_gcc_inline_asm_ssse3], + [if test "$target_cpu" != "x86_64" || + test "$try_asm_modules" != "yes" ; then + gcry_cv_gcc_inline_asm_ssse3="n/a" + else + gcry_cv_gcc_inline_asm_ssse3=no + AC_LINK_IFELSE([AC_LANG_PROGRAM( + [[static unsigned char be_mask[16] __attribute__ ((aligned (16))) = + { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; + void a(void) { + __asm__("pshufb %[mask], %%xmm2\n\t"::[mask]"m"(*be_mask):); + }]], [ a(); ] )], + [gcry_cv_gcc_inline_asm_ssse3=yes]) + fi]) +if test "$gcry_cv_gcc_inline_asm_ssse3" = "yes" ; then + CPPFLAGS_GCRY_ASM="$CPPFLAGS_GCRY_ASM -DHAVE_GCC_INLINE_ASM_SSSE3" +fi + +# +# Check whether GCC inline assembler supports SHA Extensions instructions. +# +AC_CACHE_CHECK([whether GCC inline assembler supports SHA Extensions instructions], + [gcry_cv_gcc_inline_asm_shaext], + [if test "$target_cpu" != "x86_64" || + test "$try_asm_modules" != "yes" ; then + gcry_cv_gcc_inline_asm_shaext="n/a" + else + gcry_cv_gcc_inline_asm_shaext=no + AC_LINK_IFELSE([AC_LANG_PROGRAM( + [[void a(void) { + __asm__("sha1rnds4 \$0, %%xmm1, %%xmm3\n\t":::"cc"); + __asm__("sha1nexte %%xmm1, %%xmm3\n\t":::"cc"); + __asm__("sha1msg1 %%xmm1, %%xmm3\n\t":::"cc"); + __asm__("sha1msg2 %%xmm1, %%xmm3\n\t":::"cc"); + __asm__("sha256rnds2 %%xmm0, %%xmm1, %%xmm3\n\t":::"cc"); + __asm__("sha256msg1 %%xmm1, %%xmm3\n\t":::"cc"); + __asm__("sha256msg2 %%xmm1, %%xmm3\n\t":::"cc"); + }]], [ a(); ] )], + [gcry_cv_gcc_inline_asm_shaext=yes]) + fi]) +if test "$gcry_cv_gcc_inline_asm_shaext" = "yes" ; then + CPPFLAGS_GCRY_ASM="$CPPFLAGS_GCRY_ASM -DHAVE_GCC_INLINE_ASM_SHAEXT -DENABLE_SHAEXT_SUPPORT" +fi + +# +# Check whether GCC inline assembler supports SSE4.1 instructions. +# +AC_CACHE_CHECK([whether GCC inline assembler supports SSE4.1 instructions], + [gcry_cv_gcc_inline_asm_sse41], + [if test "$target_cpu" != "x86_64" || + test "$try_asm_modules" != "yes" ; then + gcry_cv_gcc_inline_asm_sse41="n/a" + else + gcry_cv_gcc_inline_asm_sse41=no + AC_LINK_IFELSE([AC_LANG_PROGRAM( + [[void a(void) { + int i; + __asm__("pextrd \$2, %%xmm0, %[out]\n\t" : [out] "=m" (i)); + }]], [ a(); ] )], + [gcry_cv_gcc_inline_asm_sse41=yes]) + fi]) +if test "$gcry_cv_gcc_inline_asm_sse41" = "yes" ; then + AC_DEFINE(HAVE_GCC_INLINE_ASM_SSE41,1, + [Defined if inline assembler supports SSE4.1 instructions]) + CPPFLAGS_GCRY_ASM="$CPPFLAGS_GCRY_ASM -DHAVE_GCC_INLINE_ASM_SSE41" +fi + +# +# Check whether GCC inline assembler supports AVX instructions +# +AC_CACHE_CHECK([whether GCC inline assembler supports AVX instructions], + [gcry_cv_gcc_inline_asm_avx], + [if test "$target_cpu" != "x86_64" || + test "$try_asm_modules" != "yes" ; then + gcry_cv_gcc_inline_asm_avx="n/a" + else + gcry_cv_gcc_inline_asm_avx=no + AC_LINK_IFELSE([AC_LANG_PROGRAM( + [[void a(void) { + __asm__("xgetbv; vaesdeclast (%[mem]),%%xmm0,%%xmm7\n\t"::[mem]"r"(0):); + }]], [ a(); ] )], + [gcry_cv_gcc_inline_asm_avx=yes]) + fi]) +if test "$gcry_cv_gcc_inline_asm_avx" = "yes" ; then + CPPFLAGS_GCRY_ASM="$CPPFLAGS_GCRY_ASM -DHAVE_GCC_INLINE_ASM_AVX -DENABLE_AVX_SUPPORT" +fi + +# +# Check whether GCC inline assembler supports AVX2 instructions +# +AC_CACHE_CHECK([whether GCC inline assembler supports AVX2 instructions], + [gcry_cv_gcc_inline_asm_avx2], + [if test "$target_cpu" != "x86_64" || + test "$try_asm_modules" != "yes" ; then + gcry_cv_gcc_inline_asm_avx2="n/a" + else + gcry_cv_gcc_inline_asm_avx2=no + AC_LINK_IFELSE([AC_LANG_PROGRAM( + [[void a(void) { + __asm__("xgetbv; vpbroadcastb %%xmm7,%%ymm1\n\t":::"cc"); + }]], [ a(); ] )], + [gcry_cv_gcc_inline_asm_avx2=yes]) + fi]) +if test "$gcry_cv_gcc_inline_asm_avx2" = "yes" ; then + CPPFLAGS_GCRY_ASM="$CPPFLAGS_GCRY_ASM -DHAVE_GCC_INLINE_ASM_AVX2 -DENABLE_AVX2_SUPPORT" +fi + +# +# Check whether GCC inline assembler supports AVX512 instructions +# +AC_CACHE_CHECK([whether GCC inline assembler supports AVX512 instructions], + [gcry_cv_gcc_inline_asm_avx512], + [if test "$target_cpu" != "x86_64" || + test "$try_asm_modules" != "yes" ; then + gcry_cv_gcc_inline_asm_avx512="n/a" + else + gcry_cv_gcc_inline_asm_avx512=no + AC_LINK_IFELSE([AC_LANG_PROGRAM( + [[void a(void) { + __asm__("xgetbv; vpopcntq %%zmm7, %%zmm1%{%%k1%}%{z%};\n\t":::"cc"); + __asm__("vpexpandb %%zmm3, %%zmm1;\n\t":::"cc"); + __asm__("vpxorq %%xmm7, %%xmm7, %%xmm7;\n\t":::"cc"); + __asm__("vpxorq %%ymm7, %%ymm7, %%ymm7;\n\t":::"cc"); + __asm__("vpxorq (%%eax)%{1to8%}, %%zmm7, %%zmm7;\n\t":::"cc"); + }]], [ a(); ] )], + [gcry_cv_gcc_inline_asm_avx512=yes]) + fi]) +if test "$gcry_cv_gcc_inline_asm_avx512" = "yes" ; then + CPPFLAGS_GCRY_ASM="$CPPFLAGS_GCRY_ASM -DHAVE_GCC_INLINE_ASM_AVX512 -DENABLE_AVX512_SUPPORT" +fi + +# +# Check whether GCC inline assembler supports BMI2 instructions +# +AC_CACHE_CHECK([whether GCC inline assembler supports BMI2 instructions], + [gcry_cv_gcc_inline_asm_bmi2], + [if test "$target_cpu" != "x86_64" || + test "$try_asm_modules" != "yes" ; then + gcry_cv_gcc_inline_asm_bmi2="n/a" + else + gcry_cv_gcc_inline_asm_bmi2=no + AC_LINK_IFELSE([AC_LANG_PROGRAM( + [[unsigned int a(unsigned int x, unsigned int y) { + unsigned int tmp1, tmp2; + asm ("rorxl %2, %1, %0" + : "=r" (tmp1) + : "rm0" (x), "J" (32 - ((23) & 31))); + asm ("andnl %2, %1, %0" + : "=r" (tmp2) + : "r0" (x), "rm" (y)); + return tmp1 + tmp2; + }]], [ a(1, 2); ] )], + [gcry_cv_gcc_inline_asm_bmi2=yes]) + fi]) +if test "$gcry_cv_gcc_inline_asm_bmi2" = "yes" ; then + CPPFLAGS_GCRY_ASM="$CPPFLAGS_GCRY_ASM -DHAVE_GCC_INLINE_ASM_BMI2" +fi + +AC_SUBST(CPPFLAGS_GCRY_ASM) + CFLAGS="$TARGET_CFLAGS" @@ -2218,6 +2471,7 @@ AM_CONDITIONAL([COND_sparc64_ieee1275], [test x$target_cpu = xsparc64 -a x$platf AM_CONDITIONAL([COND_sparc64_emu], [test x$target_cpu = xsparc64 -a x$platform = xemu]) AM_CONDITIONAL([COND_x86_64_efi], [test x$target_cpu = xx86_64 -a x$platform = xefi]) AM_CONDITIONAL([COND_x86_64_xen], [test x$target_cpu = xx86_64 -a x$platform = xxen]) +AM_CONDITIONAL([COND_emu_hw_asm], [test x$target_cpu = xx86_64]) AM_CONDITIONAL([COND_HOST_HURD], [test x$host_kernel = xhurd]) AM_CONDITIONAL([COND_HOST_LINUX], [test x$host_kernel = xlinux]) diff --git a/include/grub/crypto.h b/include/grub/crypto.h index 4f3dd8c63..6ac51138a 100644 --- a/include/grub/crypto.h +++ b/include/grub/crypto.h @@ -585,10 +585,14 @@ unsigned int _gcry_ct_not_memequal (const void *b1, const void *b2, grub_size_t len); +#ifdef GRUB_UTIL static inline unsigned int _gcry_get_hw_features(void) { return 0; } +#else +extern unsigned int _gcry_get_hw_features(void); +#endif void *_gcry_malloc(grub_size_t n); void *_gcry_malloc_secure(grub_size_t n); -- 2.43.0 _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel