/* SPDX-License-Identifier: GPL-2.0-or-later */ #include 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); }