From 19fcec84d8d7d21e796c7624e521b60d28ee21ed Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 20:45:59 +0200 Subject: Adding upstream version 16.2.11+ds. Signed-off-by: Daniel Baumann --- src/spdk/intel-ipsec-mb/cpu_feature.c | 230 ++++++++++++++++++++++++++++++++++ 1 file changed, 230 insertions(+) create mode 100644 src/spdk/intel-ipsec-mb/cpu_feature.c (limited to 'src/spdk/intel-ipsec-mb/cpu_feature.c') diff --git a/src/spdk/intel-ipsec-mb/cpu_feature.c b/src/spdk/intel-ipsec-mb/cpu_feature.c new file mode 100644 index 000000000..15f782794 --- /dev/null +++ b/src/spdk/intel-ipsec-mb/cpu_feature.c @@ -0,0 +1,230 @@ +/******************************************************************************* + Copyright (c) 2018, Intel Corporation + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of Intel Corporation nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*******************************************************************************/ + +#include +#ifdef __WIN32 +#include +#endif + +#include "cpu_feature.h" + +struct cpuid_regs { + uint32_t eax; + uint32_t ebx; + uint32_t ecx; + uint32_t edx; +}; + +static struct cpuid_regs cpuid_1_0; +static struct cpuid_regs cpuid_7_0; + +/* + * A C wrapper for CPUID opcode + * + * Parameters: + * [in] leaf - CPUID leaf number (EAX) + * [in] subleaf - CPUID sub-leaf number (ECX) + * [out] out - registers structure to store results of CPUID into + */ +static void +__mbcpuid(const unsigned leaf, const unsigned subleaf, struct cpuid_regs *out) +{ +#ifdef _WIN32 + /* Windows */ + int regs[4]; + + __cpuidex(regs, leaf, subleaf); + out->eax = regs[0]; + out->ebx = regs[1]; + out->ecx = regs[2]; + out->edx = regs[3]; +#else + /* Linux */ + asm volatile("mov %4, %%eax\n\t" + "mov %5, %%ecx\n\t" + "cpuid\n\t" + "mov %%eax, %0\n\t" + "mov %%ebx, %1\n\t" + "mov %%ecx, %2\n\t" + "mov %%edx, %3\n\t" + : "=g" (out->eax), "=g" (out->ebx), "=g" (out->ecx), + "=g" (out->edx) + : "g" (leaf), "g" (subleaf) + : "%eax", "%ebx", "%ecx", "%edx"); +#endif /* Linux */ +} + +static uint32_t detect_shani(void) +{ + /* Check presence of SHANI - bit 29 of EBX */ + return (cpuid_7_0.ebx & (1 << 29)); +} + +static uint32_t detect_aesni(void) +{ + /* Check presence of AESNI - bit 25 of ECX */ + return (cpuid_1_0.ecx & (1 << 25)); +} + +static uint32_t detect_pclmulqdq(void) +{ + /* Check presence of PCLMULQDQ - bit 1 of ECX */ + return (cpuid_1_0.ecx & (1 << 1)); +} + +static uint32_t detect_cmov(void) +{ + /* Check presence of CMOV - bit 15 of EDX */ + return (cpuid_1_0.edx & (1 << 15)); +} + +static uint32_t detect_sse42(void) +{ + /* Check presence of SSE4.2 - bit 20 of ECX */ + return (cpuid_1_0.ecx & (1 << 20)); +} + +static uint32_t detect_avx(void) +{ + /* Check presence of AVX - bit 28 of ECX */ + return (cpuid_1_0.ecx & (1 << 28)); +} + +static uint32_t detect_avx2(void) +{ + /* Check presence of AVX2 - bit 5 of EBX */ + return (cpuid_7_0.ebx & (1 << 5)); +} + +static uint32_t detect_avx512f(void) +{ + /* Check presence of AVX512F - bit 16 of EBX */ + return (cpuid_7_0.ebx & (1 << 16)); +} + +static uint32_t detect_avx512dq(void) +{ + /* Check presence of AVX512DQ - bit 17 of EBX */ + return (cpuid_7_0.ebx & (1 << 17)); +} + +static uint32_t detect_avx512cd(void) +{ + /* Check presence of AVX512CD - bit 28 of EBX */ + return (cpuid_7_0.ebx & (1 << 28)); +} + +static uint32_t detect_avx512bw(void) +{ + /* Check presence of AVX512BW - bit 30 of EBX */ + return (cpuid_7_0.ebx & (1 << 30)); +} + +static uint32_t detect_avx512vl(void) +{ + /* Check presence of AVX512VL - bit 31 of EBX */ + return (cpuid_7_0.ebx & (1 << 31)); +} + +static uint32_t detect_vaes(void) +{ + /* Check presence of VAES - bit 9 of ECX */ + return (cpuid_7_0.ecx & (1 << 9)); +} + +static uint32_t detect_vpclmulqdq(void) +{ + /* Check presence of VAES - bit 10 of ECX */ + return (cpuid_7_0.ecx & (1 << 10)); +} + +uint64_t cpu_feature_detect(void) +{ + static const struct { + unsigned req_leaf_number; + uint64_t feat; + uint32_t (*detect_fn)(void); + } feat_tab[] = { + { 7, IMB_FEATURE_SHANI, detect_shani }, + { 1, IMB_FEATURE_AESNI, detect_aesni }, + { 1, IMB_FEATURE_PCLMULQDQ, detect_pclmulqdq }, + { 1, IMB_FEATURE_CMOV, detect_cmov }, + { 1, IMB_FEATURE_SSE4_2, detect_sse42 }, + { 1, IMB_FEATURE_AVX, detect_avx }, + { 7, IMB_FEATURE_AVX2, detect_avx2 }, + { 7, IMB_FEATURE_AVX512F, detect_avx512f }, + { 7, IMB_FEATURE_AVX512DQ, detect_avx512dq }, + { 7, IMB_FEATURE_AVX512CD, detect_avx512cd }, + { 7, IMB_FEATURE_AVX512BW, detect_avx512bw }, + { 7, IMB_FEATURE_AVX512VL, detect_avx512vl }, + { 7, IMB_FEATURE_VAES, detect_vaes }, + { 7, IMB_FEATURE_VPCLMULQDQ, detect_vpclmulqdq }, + }; + struct cpuid_regs r; + unsigned hi_leaf_number = 0; + uint64_t features = 0; + unsigned i; + + /* Get highest supported CPUID leaf number */ + __mbcpuid(0x0, 0x0, &r); + hi_leaf_number = r.eax; + + /* Get the most common CPUID leafs to speed up the detection */ + if (hi_leaf_number >= 1) + __mbcpuid(0x1, 0x0, &cpuid_1_0); + + if (hi_leaf_number >= 7) + __mbcpuid(0x7, 0x0, &cpuid_7_0); + + for (i = 0; i < IMB_DIM(feat_tab); i++) { + if (hi_leaf_number < feat_tab[i].req_leaf_number) + continue; + + if (feat_tab[i].detect_fn() != 0) + features |= feat_tab[i].feat; + } + +#ifdef SAFE_DATA + features |= IMB_FEATURE_SAFE_DATA; +#endif +#ifdef SAFE_PARAM + features |= IMB_FEATURE_SAFE_PARAM; +#endif + + return features; +} + +uint64_t cpu_feature_adjust(const uint64_t flags, uint64_t features) +{ + if (flags & IMB_FLAG_SHANI_OFF) + features &= ~IMB_FEATURE_SHANI; + + if (flags & IMB_FLAG_AESNI_OFF) + features &= ~IMB_FEATURE_AESNI; + + return features; +} -- cgit v1.2.3