diff --git a/config/kernel-objtool.m4 b/config/kernel-objtool.m4 index f9f9d657d..e616ccebc 100644 --- a/config/kernel-objtool.m4 +++ b/config/kernel-objtool.m4 @@ -11,10 +11,12 @@ AC_DEFUN([ZFS_AC_KERNEL_OBJTOOL_HEADER], [ #include ],[ ],[ + objtool_header=$LINUX/include/linux/objtool.h AC_DEFINE(HAVE_KERNEL_OBJTOOL_HEADER, 1, [kernel has linux/objtool.h]) AC_MSG_RESULT(linux/objtool.h) ],[ + objtool_header=$LINUX/include/linux/frame.h AC_MSG_RESULT(linux/frame.h) ]) ]) @@ -62,6 +64,23 @@ AC_DEFUN([ZFS_AC_KERNEL_OBJTOOL], [ AC_MSG_RESULT(yes) AC_DEFINE(HAVE_STACK_FRAME_NON_STANDARD, 1, [STACK_FRAME_NON_STANDARD is defined]) + + dnl # Needed for kernels missing the asm macro. We grep + dnl # for it in the header file since there is currently + dnl # no test to check the result of assembling a file. + AC_MSG_CHECKING( + [whether STACK_FRAME_NON_STANDARD asm macro is defined]) + dnl # Escape square brackets. + sp='@<:@@<:@:space:@:>@@:>@' + dotmacro='@<:@.@:>@macro' + regexp="^$sp*$dotmacro$sp+STACK_FRAME_NON_STANDARD$sp" + AS_IF([$EGREP -s -q "$regexp" $objtool_header],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_STACK_FRAME_NON_STANDARD_ASM, 1, + [STACK_FRAME_NON_STANDARD asm macro is defined]) + ],[ + AC_MSG_RESULT(no) + ]) ],[ AC_MSG_RESULT(no) ]) diff --git a/include/sys/frame.h b/include/sys/frame.h index dbcf1087b..fe1db28b7 100644 --- a/include/sys/frame.h +++ b/include/sys/frame.h @@ -31,8 +31,16 @@ extern "C" { #else #include #endif +#if defined(_ASM) && ! defined(HAVE_STACK_FRAME_NON_STANDARD_ASM) +.macro STACK_FRAME_NON_STANDARD func:req +.endm +#endif #else #define STACK_FRAME_NON_STANDARD(func) +#if defined(_ASM) +.macro STACK_FRAME_NON_STANDARD func:req +.endm +#endif #endif #ifdef __cplusplus diff --git a/module/icp/asm-x86_64/modes/aesni-gcm-x86_64.S b/module/icp/asm-x86_64/modes/aesni-gcm-x86_64.S index 6ff3490d3..49671f1fc 100644 --- a/module/icp/asm-x86_64/modes/aesni-gcm-x86_64.S +++ b/module/icp/asm-x86_64/modes/aesni-gcm-x86_64.S @@ -50,6 +50,7 @@ #define _ASM #include +#include /* Windows userland links with OpenSSL */ #if !defined (_WIN32) || defined (_KERNEL) @@ -378,6 +379,7 @@ FUNCTION(_aesni_ctr32_ghash_6x) RET .cfi_endproc SET_SIZE(_aesni_ctr32_ghash_6x) +STACK_FRAME_NON_STANDARD _aesni_ctr32_ghash_6x #endif /* ifdef HAVE_MOVBE */ .balign 32 @@ -706,6 +708,7 @@ FUNCTION(_aesni_ctr32_ghash_no_movbe_6x) RET .cfi_endproc SET_SIZE(_aesni_ctr32_ghash_no_movbe_6x) +STACK_FRAME_NON_STANDARD _aesni_ctr32_ghash_no_movbe_6x ENTRY_ALIGN(aesni_gcm_decrypt, 32) .cfi_startproc @@ -823,6 +826,7 @@ ENTRY_ALIGN(aesni_gcm_decrypt, 32) RET .cfi_endproc SET_SIZE(aesni_gcm_decrypt) +STACK_FRAME_NON_STANDARD aesni_gcm_decrypt .balign 32 FUNCTION(_aesni_ctr32_6x) @@ -1198,6 +1202,7 @@ ENTRY_ALIGN(aesni_gcm_encrypt, 32) RET .cfi_endproc SET_SIZE(aesni_gcm_encrypt) +STACK_FRAME_NON_STANDARD aesni_gcm_encrypt #endif /* !_WIN32 || _KERNEL */ @@ -1257,6 +1262,18 @@ SECTION_STATIC .byte 65,69,83,45,78,73,32,71,67,77,32,109,111,100,117,108,101,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 .balign 64 +/* Workaround for missing asm macro in RHEL 8. */ +#if defined(__linux__) && defined(HAVE_STACK_FRAME_NON_STANDARD) && \ + ! defined(HAVE_STACK_FRAME_NON_STANDARD_ASM) +.section .discard.func_stack_frame_non_standard, "aw" +#ifdef HAVE_MOVBE + .long _aesni_ctr32_ghash_6x - . +#endif + .long _aesni_ctr32_ghash_no_movbe_6x - . + .long aesni_gcm_decrypt - . + .long aesni_gcm_encrypt - . +#endif + /* Mark the stack non-executable. */ #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/module/icp/asm-x86_64/sha2/sha256-x86_64.S b/module/icp/asm-x86_64/sha2/sha256-x86_64.S index f19f7b471..5976f7acf 100644 --- a/module/icp/asm-x86_64/sha2/sha256-x86_64.S +++ b/module/icp/asm-x86_64/sha2/sha256-x86_64.S @@ -24,6 +24,7 @@ #define _ASM #include +#include SECTION_STATIC @@ -1420,6 +1421,7 @@ ENTRY_ALIGN(zfs_sha256_transform_x64, 16) RET .cfi_endproc SET_SIZE(zfs_sha256_transform_x64) +STACK_FRAME_NON_STANDARD zfs_sha256_transform_x64 ENTRY_ALIGN(zfs_sha256_transform_shani, 64) .cfi_startproc @@ -1628,6 +1630,7 @@ ENTRY_ALIGN(zfs_sha256_transform_shani, 64) RET .cfi_endproc SET_SIZE(zfs_sha256_transform_shani) +STACK_FRAME_NON_STANDARD zfs_sha256_transform_shani ENTRY_ALIGN(zfs_sha256_transform_ssse3, 64) .cfi_startproc @@ -2739,6 +2742,7 @@ ENTRY_ALIGN(zfs_sha256_transform_ssse3, 64) RET .cfi_endproc SET_SIZE(zfs_sha256_transform_ssse3) +STACK_FRAME_NON_STANDARD zfs_sha256_transform_ssse3 ENTRY_ALIGN(zfs_sha256_transform_avx, 64) .cfi_startproc @@ -3813,6 +3817,7 @@ ENTRY_ALIGN(zfs_sha256_transform_avx, 64) RET .cfi_endproc SET_SIZE(zfs_sha256_transform_avx) +STACK_FRAME_NON_STANDARD zfs_sha256_transform_avx ENTRY_ALIGN(zfs_sha256_transform_avx2, 64) .cfi_startproc @@ -5098,6 +5103,18 @@ ENTRY_ALIGN(zfs_sha256_transform_avx2, 64) RET .cfi_endproc SET_SIZE(zfs_sha256_transform_avx2) +STACK_FRAME_NON_STANDARD zfs_sha256_transform_avx2 + +/* Workaround for missing asm macro in RHEL 8. */ +#if defined(__linux__) && defined(HAVE_STACK_FRAME_NON_STANDARD) && \ + ! defined(HAVE_STACK_FRAME_NON_STANDARD_ASM) +.section .discard.func_stack_frame_non_standard, "aw" + .long zfs_sha256_transform_x64 - . + .long zfs_sha256_transform_shani - . + .long zfs_sha256_transform_ssse3 - . + .long zfs_sha256_transform_avx - . + .long zfs_sha256_transform_avx2 - . +#endif #if defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/module/icp/asm-x86_64/sha2/sha512-x86_64.S b/module/icp/asm-x86_64/sha2/sha512-x86_64.S index a5111d501..9ed50ddc7 100644 --- a/module/icp/asm-x86_64/sha2/sha512-x86_64.S +++ b/module/icp/asm-x86_64/sha2/sha512-x86_64.S @@ -24,6 +24,7 @@ #define _ASM #include +#include SECTION_STATIC @@ -1463,6 +1464,7 @@ ENTRY_ALIGN(zfs_sha512_transform_x64, 16) RET .cfi_endproc SET_SIZE(zfs_sha512_transform_x64) +STACK_FRAME_NON_STANDARD zfs_sha512_transform_x64 ENTRY_ALIGN(zfs_sha512_transform_avx, 64) .cfi_startproc @@ -2627,6 +2629,7 @@ ENTRY_ALIGN(zfs_sha512_transform_avx, 64) RET .cfi_endproc SET_SIZE(zfs_sha512_transform_avx) +STACK_FRAME_NON_STANDARD zfs_sha512_transform_avx ENTRY_ALIGN(zfs_sha512_transform_avx2, 64) .cfi_startproc @@ -4005,6 +4008,16 @@ ENTRY_ALIGN(zfs_sha512_transform_avx2, 64) RET .cfi_endproc SET_SIZE(zfs_sha512_transform_avx2) +STACK_FRAME_NON_STANDARD zfs_sha512_transform_avx2 + +/* Workaround for missing asm macro in RHEL 8. */ +#if defined(__linux__) && defined(HAVE_STACK_FRAME_NON_STANDARD) && \ + ! defined(HAVE_STACK_FRAME_NON_STANDARD_ASM) +.section .discard.func_stack_frame_non_standard, "aw" + .long zfs_sha512_transform_x64 - . + .long zfs_sha512_transform_avx - . + .long zfs_sha512_transform_avx2 - . +#endif #if defined(__ELF__) .section .note.GNU-stack,"",%progbits