| /* SPDX-License-Identifier: GPL-2.0-or-later */ | |
| #include <asm/cpufeature.h> | |
| extern const struct raid6_calls raid6_mmxx1; | |
| extern const struct raid6_calls raid6_mmxx2; | |
| extern const struct raid6_calls raid6_sse1x1; | |
| extern const struct raid6_calls raid6_sse1x2; | |
| extern const struct raid6_calls raid6_sse2x1; | |
| extern const struct raid6_calls raid6_sse2x2; | |
| extern const struct raid6_calls raid6_sse2x4; | |
| extern const struct raid6_calls raid6_avx2x1; | |
| extern const struct raid6_calls raid6_avx2x2; | |
| extern const struct raid6_calls raid6_avx2x4; | |
| extern const struct raid6_calls raid6_avx512x1; | |
| extern const struct raid6_calls raid6_avx512x2; | |
| extern const struct raid6_calls raid6_avx512x4; | |
| extern const struct raid6_recov_calls raid6_recov_ssse3; | |
| extern const struct raid6_recov_calls raid6_recov_avx2; | |
| extern const struct raid6_recov_calls raid6_recov_avx512; | |
| static inline int raid6_has_avx512(void) | |
| { | |
| return boot_cpu_has(X86_FEATURE_AVX2) && | |
| boot_cpu_has(X86_FEATURE_AVX) && | |
| boot_cpu_has(X86_FEATURE_AVX512F) && | |
| boot_cpu_has(X86_FEATURE_AVX512BW) && | |
| boot_cpu_has(X86_FEATURE_AVX512VL) && | |
| boot_cpu_has(X86_FEATURE_AVX512DQ); | |
| } | |
| static inline bool raid6_has_avx2(void) | |
| { | |
| return boot_cpu_has(X86_FEATURE_AVX2) && boot_cpu_has(X86_FEATURE_AVX); | |
| } | |
| static inline bool raid6_has_ssse3(void) | |
| { | |
| return boot_cpu_has(X86_FEATURE_XMM) && | |
| boot_cpu_has(X86_FEATURE_XMM2) && | |
| boot_cpu_has(X86_FEATURE_SSSE3); | |
| } | |
| static inline bool raid6_has_sse2(void) | |
| { | |
| return boot_cpu_has(X86_FEATURE_MMX) && | |
| boot_cpu_has(X86_FEATURE_FXSR) && | |
| boot_cpu_has(X86_FEATURE_XMM) && | |
| boot_cpu_has(X86_FEATURE_XMM2); | |
| } | |
| static inline bool raid6_has_sse1_or_mmxext(void) | |
| { | |
| return boot_cpu_has(X86_FEATURE_MMX) && | |
| (boot_cpu_has(X86_FEATURE_XMM) || | |
| boot_cpu_has(X86_FEATURE_MMXEXT)); | |
| } | |
| static __always_inline void __init arch_raid6_init(void) | |
| { | |
| if (raid6_has_avx2()) { | |
| raid6_algo_add(&raid6_avx2x1); | |
| raid6_algo_add(&raid6_avx2x2); | |
| if (IS_ENABLED(CONFIG_X86_64)) | |
| raid6_algo_add(&raid6_avx2x4); | |
| if (raid6_has_avx512()) { | |
| raid6_algo_add(&raid6_avx512x1); | |
| raid6_algo_add(&raid6_avx512x2); | |
| if (IS_ENABLED(CONFIG_X86_64)) | |
| raid6_algo_add(&raid6_avx512x4); | |
| } | |
| } else if (IS_ENABLED(CONFIG_X86_64) || raid6_has_sse2()) { | |
| /* x86_64 can assume SSE2 as baseline */ | |
| raid6_algo_add(&raid6_sse2x1); | |
| raid6_algo_add(&raid6_sse2x2); | |
| if (IS_ENABLED(CONFIG_X86_64)) | |
| raid6_algo_add(&raid6_sse2x4); | |
| } else { | |
| raid6_algo_add_default(); | |
| if (raid6_has_sse1_or_mmxext()) { | |
| raid6_algo_add(&raid6_sse1x1); | |
| raid6_algo_add(&raid6_sse1x2); | |
| } else if (boot_cpu_has(X86_FEATURE_MMX)) { | |
| raid6_algo_add(&raid6_mmxx1); | |
| raid6_algo_add(&raid6_mmxx2); | |
| } | |
| } | |
| if (raid6_has_avx512()) | |
| raid6_recov_algo_add(&raid6_recov_avx512); | |
| else if (raid6_has_avx2()) | |
| raid6_recov_algo_add(&raid6_recov_avx2); | |
| else if (raid6_has_ssse3()) | |
| raid6_recov_algo_add(&raid6_recov_ssse3); | |
| } |