From 9e803591e34919f50313f2ff546102eedc025ebb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20F=C3=BCl=C3=B6p?= Date: Wed, 1 Mar 2023 18:59:44 +0100 Subject: [PATCH 1/2] Linux x86 SIMD: Add XSAVEC support to kfpu_begin() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since there is a register restore bug in XSAVES and XRSTORS add and use XSAVEC if available. Signed-off-by: Attila Fülöp --- config/toolchain-simd.m4 | 22 ++++++++++++++++++++++ include/os/linux/kernel/linux/simd_x86.h | 6 ++++++ 2 files changed, 28 insertions(+) diff --git a/config/toolchain-simd.m4 b/config/toolchain-simd.m4 index 061576fd94..4ccccc2e3e 100644 --- a/config/toolchain-simd.m4 +++ b/config/toolchain-simd.m4 @@ -27,6 +27,7 @@ AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_TOOLCHAIN_SIMD], [ ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_XSAVE ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_XSAVEOPT ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_XSAVES + ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_XSAVEC ;; esac ]) @@ -488,3 +489,24 @@ AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_XSAVES], [ AC_MSG_RESULT([no]) ]) ]) + +dnl # +dnl # ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_XSAVEC +dnl # +AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_XSAVEC], [ + AC_MSG_CHECKING([whether host toolchain supports XSAVEC]) + + AC_LINK_IFELSE([AC_LANG_SOURCE([ + [ + void main() + { + char b[4096] __attribute__ ((aligned (64))); + __asm__ __volatile__("xsavec %[b]\n" : : [b] "m" (*b) : "memory"); + } + ]])], [ + AC_MSG_RESULT([yes]) + AC_DEFINE([HAVE_XSAVEC], 1, [Define if host toolchain supports XSAVEC]) + ], [ + AC_MSG_RESULT([no]) + ]) +]) diff --git a/include/os/linux/kernel/linux/simd_x86.h b/include/os/linux/kernel/linux/simd_x86.h index 2f6c3165ac..ff4e2466d5 100644 --- a/include/os/linux/kernel/linux/simd_x86.h +++ b/include/os/linux/kernel/linux/simd_x86.h @@ -311,6 +311,12 @@ kfpu_begin(void) * FPU state to be correctly preserved and restored. */ uint8_t *state = zfs_kfpu_fpregs[smp_processor_id()]; +#if defined(HAVE_XSAVEC) + if (static_cpu_has(X86_FEATURE_XSAVEC)) { + kfpu_do_xsave("xsavec", state, ~0); + return; + } +#endif #if defined(HAVE_XSAVES) if (static_cpu_has(X86_FEATURE_XSAVES)) { kfpu_do_xsave("xsaves", state, ~0); From 6877642528074a0275b869c7d7b1207652e66f44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20F=C3=BCl=C3=B6p?= Date: Wed, 1 Mar 2023 19:29:47 +0100 Subject: [PATCH 2/2] Use XRSTOR with XSAVEC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Attila Fülöp --- include/os/linux/kernel/linux/simd_x86.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/os/linux/kernel/linux/simd_x86.h b/include/os/linux/kernel/linux/simd_x86.h index ff4e2466d5..bd987f08c9 100644 --- a/include/os/linux/kernel/linux/simd_x86.h +++ b/include/os/linux/kernel/linux/simd_x86.h @@ -378,6 +378,13 @@ static inline void kfpu_end(void) { uint8_t *state = zfs_kfpu_fpregs[smp_processor_id()]; + +#if defined(HAVE_XSAVEC) + if (static_cpu_has(X86_FEATURE_XSAVEC)) { + kfpu_do_xrstor("xrstor", state, ~0); + goto out; + } +#endif #if defined(HAVE_XSAVES) if (static_cpu_has(X86_FEATURE_XSAVES)) { kfpu_do_xrstor("xrstors", state, ~0);