From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-qv1-xf35.google.com (mail-qv1-xf35.google.com [IPv6:2607:f8b0:4864:20::f35]) by sourceware.org (Postfix) with ESMTPS id 05BD3394742E for ; Wed, 6 Jan 2021 12:01:02 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 05BD3394742E Received: by mail-qv1-xf35.google.com with SMTP id s6so1095411qvn.6 for ; Wed, 06 Jan 2021 04:01:02 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:to:references:from:autocrypt:subject:message-id :date:user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=rGbMp4BAMNGD4vVyCDz/8dI4BLDU+j2jPbZVMaK9wZE=; b=m8VNyjl8FoFvrPttKQgpGN6Od5h1qGmUUpNPezpvZ6hOPcLtbYfJoxdHd1U3k49BZ4 p3f36Udnerl5VMMmo9a79LluMV9ok2PgZik53nxZbH0SXR4XeLlfwYpClv13MXVxeuE+ 5cVkxvrZN4C4CnfLYtDvjqjioc9/69gf/UrK+pYsAFvLMICNcrb2vRQDUqNneLh4Zf6Q W9kf/ZS6+D0GUorOsC63BJJlePM4A95z8ewtddY3QD38iltxwk2rI2vgTmfSBd/oStoE mBSQ7l8x5EZP9BOdq+L7zhatZy6h+EG1LttiTxWYZWPXx/xNi//vRgiJVQCNLCwN9l1X InqA== X-Gm-Message-State: AOAM530VI54Yq+ZQsv4jQKrPROCWMBxIzOUisqA9NAHD0LE5sNBo8T7j EEMfcf/Tc6j3CfYhrIZ0P95tdw== X-Google-Smtp-Source: ABdhPJyasqjjwq4rlD/eor9Vg3EYgiDz8/2jm7nyirN+fujcWCPmWQbdbLyes5PN5HNrG00OnZLTRw== X-Received: by 2002:a0c:e651:: with SMTP id c17mr3760530qvn.34.1609934460849; Wed, 06 Jan 2021 04:01:00 -0800 (PST) Received: from [192.168.1.4] ([177.194.48.209]) by smtp.googlemail.com with ESMTPSA id b12sm974421qtj.12.2021.01.06.04.00.58 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 06 Jan 2021 04:01:00 -0800 (PST) To: libc-alpha@sourceware.org, "H.J. Lu" , Florian Weimer References: <20201206144952.2109594-1-hjl.tools@gmail.com> <20201206144952.2109594-2-hjl.tools@gmail.com> From: Adhemerval Zanella Autocrypt: addr=adhemerval.zanella@linaro.org; prefer-encrypt=mutual; keydata= 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 Subject: Re: V5 [PATCH 1/2] x86: Support GNU_PROPERTY_X86_ISA_1_V[234] marker [BZ #26717] Message-ID: <83ab601d-adbe-6d26-8d9c-235d52503171@linaro.org> Date: Wed, 6 Jan 2021 09:00:56 -0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.10.0 MIME-Version: 1.0 In-Reply-To: <20201206144952.2109594-2-hjl.tools@gmail.com> Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-14.0 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, NICE_REPLY_A, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 06 Jan 2021 12:01:09 -0000 On 06/12/2020 11:49, H.J. Lu via Libc-alpha wrote: > GCC 11 supports -march=x86-64-v[234] to enable x86 micro-architecture ISA > levels: > > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97250 > > and -mneeded to emit GNU_PROPERTY_X86_ISA_1_NEEDED property with > GNU_PROPERTY_X86_ISA_1_V[234] marker: > > https://gitlab.com/x86-psABIs/x86-64-ABI/-/merge_requests/13 > > Binutils support for GNU_PROPERTY_X86_ISA_1_V[234] marker were added by > > commit b0ab06937385e0ae25cebf1991787d64f439bf12 > Author: H.J. Lu > Date: Fri Oct 30 06:49:57 2020 -0700 > > x86: Support GNU_PROPERTY_X86_ISA_1_BASELINE marker > > and > > commit 32930e4edbc06bc6f10c435dbcc63131715df678 > Author: H.J. Lu > Date: Fri Oct 9 05:05:57 2020 -0700 > > x86: Support GNU_PROPERTY_X86_ISA_1_V[234] marker > > GNU_PROPERTY_X86_ISA_1_NEEDED property in x86 ELF binaries indicate the > micro-architecture ISA level required to execute the binary. The marker > must be added by programmers explicitly in one of 3 ways: > > 1. Pass -mneeded to GCC. > 2. Add the marker in the linker inputs as this patch does. > 3. Pass -z x86-64-v[234] to the linker. > > Add GNU_PROPERTY_X86_ISA_1_BASELINE and GNU_PROPERTY_X86_ISA_1_V[234] > marker support to ld.so if binutils 2.32 or newer is used to build glibc: > > 1. Add GNU_PROPERTY_X86_ISA_1_BASELINE and GNU_PROPERTY_X86_ISA_1_V[234] > markers to elf.h. > 2. Add GNU_PROPERTY_X86_ISA_1_BASELINE and GNU_PROPERTY_X86_ISA_1_V[234] > marker to abi-note.o based on the ISA level used to compile abi-note.o, > assuming that the same ISA level is used to compile the whole glibc. > 3. Add isa_1 to cpu_features to record the supported x86 ISA level. > 4. Rename _dl_process_cet_property_note to _dl_process_property_note and > add GNU_PROPERTY_X86_ISA_1_V[234] marker detection. > 5. Update _rtld_main_check and _dl_open_check to check loaded objects > with the incompatible ISA level. > 6. Add a testcase to verify that dlopen an x86-64-v4 shared object fails > on lesser platforms. > 7. Use in dl-hwcaps-subdirs.c and tst-glibc-hwcaps.c. > > Marked elf/tst-isa-level-1 with x86-64-v4, ran it on x86-64-v3 machine > and got: > > [hjl@gnu-cfl-2 build-x86_64-linux]$ ./elf/tst-isa-level-1 > ./elf/tst-isa-level-1: CPU ISA level is lower than required > [hjl@gnu-cfl-2 build-x86_64-linux]$ > --- > config.h.in | 3 + > elf/elf.h | 35 ++++----- > sysdeps/x86/Makefile | 10 +++ > sysdeps/x86/abi-note.c | 29 ++++++++ > sysdeps/x86/configure | 101 ++++++++++++++++++++++++++ > sysdeps/x86/configure.ac | 26 +++++++ > sysdeps/x86/cpu-features.c | 3 + > sysdeps/x86/dl-cet.c | 12 ++- > sysdeps/x86/dl-prop.h | 113 +++++++++++++++++++++-------- > sysdeps/x86/get-isa-level.h | 66 +++++++++++++++++ > sysdeps/x86/include/cpu-features.h | 2 + > sysdeps/x86/isa-level.c | 95 ++++++++++++++++++++++++ > sysdeps/x86/link_map.h | 18 +++-- > sysdeps/x86/tst-isa-level-1.c | 74 +++++++++++++++++++ > sysdeps/x86/tst-isa-level-mod-1.c | 23 ++++++ > sysdeps/x86/tst-isa-level-mod-1a.c | 2 + > sysdeps/x86/tst-isa-level-mod-1b.c | 1 + > sysdeps/x86_64/dl-hwcaps-subdirs.c | 30 ++------ > sysdeps/x86_64/tst-glibc-hwcaps.c | 41 +++-------- > 19 files changed, 571 insertions(+), 113 deletions(-) > create mode 100644 sysdeps/x86/abi-note.c > create mode 100644 sysdeps/x86/get-isa-level.h > create mode 100644 sysdeps/x86/isa-level.c > create mode 100644 sysdeps/x86/tst-isa-level-1.c > create mode 100644 sysdeps/x86/tst-isa-level-mod-1.c > create mode 100644 sysdeps/x86/tst-isa-level-mod-1a.c > create mode 100644 sysdeps/x86/tst-isa-level-mod-1b.c > > diff --git a/config.h.in b/config.h.in > index b823c8e080..dc3854f4eb 100644 > --- a/config.h.in > +++ b/config.h.in > @@ -266,4 +266,7 @@ > /* The default value of x86 CET control. */ > #define DEFAULT_DL_X86_CET_CONTROL cet_elf_property > > +/* Define if x86 ISA level should be included in shared libraries. */ > +#undef INCLUDE_X86_ISA_LEVEL > + > #endif > diff --git a/elf/elf.h b/elf/elf.h > index bd7af7cca4..42fd697129 100644 > --- a/elf/elf.h > +++ b/elf/elf.h > @@ -1325,31 +1325,26 @@ typedef struct > > /* The x86 instruction sets indicated by the corresponding bits are > used in program. Their support in the hardware is optional. */ > -#define GNU_PROPERTY_X86_ISA_1_USED 0xc0000000 > +#define GNU_PROPERTY_X86_ISA_1_USED 0xc0010002 > /* The x86 instruction sets indicated by the corresponding bits are > used in program and they must be supported by the hardware. */ > -#define GNU_PROPERTY_X86_ISA_1_NEEDED 0xc0000001 > +#define GNU_PROPERTY_X86_ISA_1_NEEDED 0xc0008002 > /* X86 processor-specific features used in program. */ > #define GNU_PROPERTY_X86_FEATURE_1_AND 0xc0000002 > > -#define GNU_PROPERTY_X86_ISA_1_486 (1U << 0) > -#define GNU_PROPERTY_X86_ISA_1_586 (1U << 1) > -#define GNU_PROPERTY_X86_ISA_1_686 (1U << 2) > -#define GNU_PROPERTY_X86_ISA_1_SSE (1U << 3) > -#define GNU_PROPERTY_X86_ISA_1_SSE2 (1U << 4) > -#define GNU_PROPERTY_X86_ISA_1_SSE3 (1U << 5) > -#define GNU_PROPERTY_X86_ISA_1_SSSE3 (1U << 6) > -#define GNU_PROPERTY_X86_ISA_1_SSE4_1 (1U << 7) > -#define GNU_PROPERTY_X86_ISA_1_SSE4_2 (1U << 8) > -#define GNU_PROPERTY_X86_ISA_1_AVX (1U << 9) > -#define GNU_PROPERTY_X86_ISA_1_AVX2 (1U << 10) > -#define GNU_PROPERTY_X86_ISA_1_AVX512F (1U << 11) > -#define GNU_PROPERTY_X86_ISA_1_AVX512CD (1U << 12) > -#define GNU_PROPERTY_X86_ISA_1_AVX512ER (1U << 13) > -#define GNU_PROPERTY_X86_ISA_1_AVX512PF (1U << 14) > -#define GNU_PROPERTY_X86_ISA_1_AVX512VL (1U << 15) > -#define GNU_PROPERTY_X86_ISA_1_AVX512DQ (1U << 16) > -#define GNU_PROPERTY_X86_ISA_1_AVX512BW (1U << 17) > +/* GNU_PROPERTY_X86_ISA_1_BASELINE: CMOV, CX8 (cmpxchg8b), FPU (fld), > + MMX, OSFXSR (fxsave), SCE (syscall), SSE and SSE2. */ > +#define GNU_PROPERTY_X86_ISA_1_BASELINE (1U << 0) > +/* GNU_PROPERTY_X86_ISA_1_V2: GNU_PROPERTY_X86_ISA_1_BASELINE, > + CMPXCHG16B (cmpxchg16b), LAHF-SAHF (lahf), POPCNT (popcnt), SSE3, > + SSSE3, SSE4.1 and SSE4.2. */ > +#define GNU_PROPERTY_X86_ISA_1_V2 (1U << 1) > +/* GNU_PROPERTY_X86_ISA_1_V3: GNU_PROPERTY_X86_ISA_1_V2, AVX, AVX2, BMI1, > + BMI2, F16C, FMA, LZCNT, MOVBE, XSAVE. */ > +#define GNU_PROPERTY_X86_ISA_1_V3 (1U << 2) > +/* GNU_PROPERTY_X86_ISA_1_V4: GNU_PROPERTY_X86_ISA_1_V3, AVX512F, > + AVX512BW, AVX512CD, AVX512DQ and AVX512VL. */ > +#define GNU_PROPERTY_X86_ISA_1_V4 (1U << 3) > > /* This indicates that all executable sections are compatible with > IBT. */ Shouldn't it follow bintuils 32930e4edbc06 change and move current GNU_PROPERTY_X86_ISA_1_ definitions to GNU_PROPERTY_X86_COMPAT_2_? Not sure if this charecterize any exported ABI change, since the most possible usual consumer (bintuils) does not use glibc version. Also, maybe move this change to an specific patch. > diff --git a/sysdeps/x86/Makefile b/sysdeps/x86/Makefile > index 081cc72e93..109f03e9b9 100644 > --- a/sysdeps/x86/Makefile > +++ b/sysdeps/x86/Makefile > @@ -9,6 +9,16 @@ sysdep_headers += sys/platform/x86.h > tests += tst-get-cpu-features tst-get-cpu-features-static \ > tst-cpu-features-cpuinfo tst-cpu-features-supports > tests-static += tst-get-cpu-features-static > +ifeq (yesyes,$(enable-x86-isa-level)$(config-cflags-skylake-avx512)) > +tests += tst-isa-level-1 > +modules-names += tst-isa-level-mod-1a tst-isa-level-mod-1b > + > +CFLAGS-tst-isa-level-mod-1a.c += -march=skylake-avx512 \ > + -DINCLUDE_X86_ISA_LEVEL > +$(objpfx)tst-isa-level-1: $(libdl) > +$(objpfx)tst-isa-level-1.out: $(objpfx)tst-isa-level-mod-1a.so \ > + $(objpfx)tst-isa-level-mod-1b.so > +endif > endif > > ifeq ($(subdir),math) This will limit the test to a very narrow set of machines, couldn't we check only for enable-x86-isa-level and make the conditional check for ISA inside the test itself? What I have in mind would be something like: 1. Create onde module object for each ISA variant, by varying either -march or using the specific gcc option (not sure it would clash with the ABI notes isa-level.c already include). 2. On tst-isa-level-1.c check current ISA level with get_isa_level and check against the ISA_BASELINE and load the modules with a ISA number lower than baseline. Something like: const struct cpu_features *cpu_features = __x86_get_cpu_features (COMMON_CPUID_INDEX_MAX); unsigned int isa_level = get_isa_level (cpu_features); bool check_isa_baseline = (isa_level & ISA_BASELINE) == ISA_BASELINE; bool check_isa_v2 = (isa_level & ISA_V2) == ISA_V2; bool check_isa_v3 = (isa_level & ISA_V3) == ISA_V3; bool check_isa_v4 = (isa_level & ISA_V4) == ISA_V4; do_test_1 ("tst-isa-level-mod-1-baseline.so", true); do_test_1 ("tst-isa-level-mod-1-isa_v2.so", true); do_test_1 ("tst-isa-level-mod-1-isa_v3.so", true); do_test_1 ("tst-isa-level-mod-1-isa_v4.so", true); You might require to just build the isa_v4 only for config-cflags-skylake-avx512 and conditionalize with HAVE_SKYLAKE_AVX512_SUPPORT (which seems to be ununsed in this patch). > diff --git a/sysdeps/x86/abi-note.c b/sysdeps/x86/abi-note.c > new file mode 100644 > index 0000000000..5140e6ab47 > --- /dev/null > +++ b/sysdeps/x86/abi-note.c > @@ -0,0 +1,29 @@ > +/* Special .init and .fini section support. x86-64 version. > + Copyright (C) 2020 Free Software Foundation, Inc. > + This file is part of the GNU C Library. > + > + The GNU C Library is free software; you can redistribute it and/or > + modify it under the terms of the GNU Lesser General Public > + License as published by the Free Software Foundation; either > + version 2.1 of the License, or (at your option) any later version. > + > + In addition to the permissions in the GNU Lesser General Public > + License, the Free Software Foundation gives you unlimited > + permission to link the compiled version of this file with other > + programs, and to distribute those programs without any restriction > + coming from the use of this file. (The Lesser General Public > + License restrictions do apply in other respects; for example, they > + cover modification of the file, and distribution when not linked > + into another program.) > + > + The GNU C Library is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + Lesser General Public License for more details. > + > + You should have received a copy of the GNU Lesser General Public > + License along with the GNU C Library; if not, see > + . */ > + > +#include > +#include Ok, > diff --git a/sysdeps/x86/configure b/sysdeps/x86/configure > index 81cc4e80d6..2738fe47b2 100644 > --- a/sysdeps/x86/configure > +++ b/sysdeps/x86/configure > @@ -68,3 +68,104 @@ elif test $enable_cet = permissive; then > fi > config_vars="$config_vars > enable-cet = $enable_cet" > + > +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -march=skylake-avx512 support" >&5 > +$as_echo_n "checking for -march=skylake-avx512 support... " >&6; } > +if ${libc_cv_cc_skylake_avx512+:} false; then : > + $as_echo_n "(cached) " >&6 > +else > + if { ac_try='${CC-cc} -march=skylake-avx512 -xc /dev/null -S -o /dev/null' > + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 > + (eval $ac_try) 2>&5 > + ac_status=$? > + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 > + test $ac_status = 0; }; }; then : > + libc_cv_cc_skylake_avx512=yes > +else > + libc_cv_cc_skylake_avx512=no > +fi > + > +fi > +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_cc_skylake_avx512" >&5 > +$as_echo "$libc_cv_cc_skylake_avx512" >&6; } > +if test $libc_cv_cc_skylake_avx512 = yes; then > + $as_echo "#define HAVE_SKYLAKE_AVX512_SUPPORT 1" >>confdefs.h > + > +fi > +config_vars="$config_vars > +config-cflags-skylake-avx512 = $libc_cv_cc_skylake_avx512" > + > +libc_cv_include_x86_isa_level=no > +if test -z "`$LD --version | sed -n 's/^GNU \(gold\).*$/\1/p'`"; then > + # Check for ld 2.32 or higher. > + libc_cv_include_x86_isa_level=yes > + for ac_prog in $LD > +do > + # Extract the first word of "$ac_prog", so it can be a program name with args. > +set dummy $ac_prog; ac_word=$2 > +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 > +$as_echo_n "checking for $ac_word... " >&6; } > +if ${ac_cv_prog_LD+:} false; then : > + $as_echo_n "(cached) " >&6 > +else > + if test -n "$LD"; then > + ac_cv_prog_LD="$LD" # Let the user override the test. > +else > +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR > +for as_dir in $PATH > +do > + IFS=$as_save_IFS > + test -z "$as_dir" && as_dir=. > + for ac_exec_ext in '' $ac_executable_extensions; do > + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then > + ac_cv_prog_LD="$ac_prog" > + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 > + break 2 > + fi > +done > + done > +IFS=$as_save_IFS > + > +fi > +fi > +LD=$ac_cv_prog_LD > +if test -n "$LD"; then > + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5 > +$as_echo "$LD" >&6; } > +else > + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 > +$as_echo "no" >&6; } > +fi > + > + > + test -n "$LD" && break > +done > + > +if test -z "$LD"; then > + ac_verc_fail=yes > +else > + # Found it, now check the version. > + { $as_echo "$as_me:${as_lineno-$LINENO}: checking version of $LD" >&5 > +$as_echo_n "checking version of $LD... " >&6; } > + ac_prog_version=`$LD --version 2>&1 | sed -n 's/^.*GNU ld.* \([0-9][0-9]*\.[0-9.]*\).*$/\1/p'` > + case $ac_prog_version in > + '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;; > + 2.3[2-9]*|2.[4-9][0-9]*|[3-9].*|[1-9][0-9]*) > + ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;; > + *) ac_prog_version="$ac_prog_version, bad"; ac_verc_fail=yes;; > + > + esac > + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_prog_version" >&5 > +$as_echo "$ac_prog_version" >&6; } > +fi > +if test $ac_verc_fail = yes; then > + libc_cv_include_x86_isa_level=no > +fi > + > + if test $libc_cv_include_x86_isa_level = yes; then > + $as_echo "#define INCLUDE_X86_ISA_LEVEL 1" >>confdefs.h > + > + fi > +fi > +config_vars="$config_vars > +enable-x86-isa-level = $libc_cv_include_x86_isa_level" > diff --git a/sysdeps/x86/configure.ac b/sysdeps/x86/configure.ac > index 8f3e1191f6..8f00b9663d 100644 > --- a/sysdeps/x86/configure.ac > +++ b/sysdeps/x86/configure.ac > @@ -43,3 +43,29 @@ elif test $enable_cet = permissive; then > AC_DEFINE(DEFAULT_DL_X86_CET_CONTROL, cet_permissive) > fi > LIBC_CONFIG_VAR([enable-cet], [$enable_cet]) > + > +dnl Check if -march=skylake-avx512 works. > +AC_CACHE_CHECK(for -march=skylake-avx512 support, > + libc_cv_cc_skylake_avx512, [dnl > +LIBC_TRY_CC_OPTION([-march=skylake-avx512], > + [libc_cv_cc_skylake_avx512=yes], > + [libc_cv_cc_skylake_avx512=no]) > +]) > +if test $libc_cv_cc_skylake_avx512 = yes; then > + AC_DEFINE(HAVE_SKYLAKE_AVX512_SUPPORT) > +fi Where is it used specifically? There is no config.h.in tag either. > +LIBC_CONFIG_VAR([config-cflags-skylake-avx512], [$libc_cv_cc_skylake_avx512]) > + > +libc_cv_include_x86_isa_level=no > +if test -z "`$LD --version | sed -n 's/^GNU \(gold\).*$/\1/p'`"; then > + # Check for ld 2.32 or higher. > + libc_cv_include_x86_isa_level=yes > + AC_CHECK_PROG_VER(LD, $LD, --version, > + [GNU ld.* \([0-9][0-9]*\.[0-9.]*\)], > + [2.3[2-9]*|2.[4-9][0-9]*|[3-9].*|[1-9][0-9]*], > + libc_cv_include_x86_isa_level=no) > + if test $libc_cv_include_x86_isa_level = yes; then > + AC_DEFINE(INCLUDE_X86_ISA_LEVEL) > + fi > +fi > +LIBC_CONFIG_VAR([enable-x86-isa-level], [$libc_cv_include_x86_isa_level]) Instead of version check, would it better to check if the linker actually build a snippet with the expected notes? > diff --git a/sysdeps/x86/cpu-features.c b/sysdeps/x86/cpu-features.c > index fe080b63b2..ec5cdafe81 100644 > --- a/sysdeps/x86/cpu-features.c > +++ b/sysdeps/x86/cpu-features.c > @@ -19,6 +19,7 @@ > #include > #include > #include > +#include > #if IS_IN (libc) && !defined SHARED > # include > # include > @@ -290,6 +291,8 @@ update_usable (struct cpu_features *cpu_features) > CPU_FEATURE_SET_USABLE (cpu_features, KL); > CPU_FEATURE_SET_USABLE (cpu_features, WIDE_KL); > } > + > + cpu_features->isa_1 = get_isa_level (cpu_features); > } > > static void Ok. > diff --git a/sysdeps/x86/dl-cet.c b/sysdeps/x86/dl-cet.c > index 5524b66038..8986c776e5 100644 > --- a/sysdeps/x86/dl-cet.c > +++ b/sysdeps/x86/dl-cet.c > @@ -76,10 +76,12 @@ dl_cet_check (struct link_map *m, const char *program) > */ > enable_ibt &= (HAS_CPU_FEATURE (IBT) > && (enable_ibt_type == cet_always_on > - || (m->l_cet & lc_ibt) != 0)); > + || (m->l_x86_feature_1_and > + & GNU_PROPERTY_X86_FEATURE_1_IBT) != 0)); > enable_shstk &= (HAS_CPU_FEATURE (SHSTK) > && (enable_shstk_type == cet_always_on > - || (m->l_cet & lc_shstk) != 0)); > + || (m->l_x86_feature_1_and > + & GNU_PROPERTY_X86_FEATURE_1_SHSTK) != 0)); > } > Ok. > /* ld.so is CET-enabled by kernel. But shared objects may not > @@ -111,7 +113,8 @@ dl_cet_check (struct link_map *m, const char *program) > /* IBT is enabled only if it is enabled in executable as > well as all shared objects. */ > enable_ibt &= (enable_ibt_type == cet_always_on > - || (l->l_cet & lc_ibt) != 0); > + || (l->l_x86_feature_1_and > + & GNU_PROPERTY_X86_FEATURE_1_IBT) != 0); > if (!found_ibt_legacy && enable_ibt != ibt_enabled) > { > found_ibt_legacy = true; > @@ -121,7 +124,8 @@ dl_cet_check (struct link_map *m, const char *program) > /* SHSTK is enabled only if it is enabled in executable as > well as all shared objects. */ > enable_shstk &= (enable_shstk_type == cet_always_on > - || (l->l_cet & lc_shstk) != 0); > + || (l->l_x86_feature_1_and > + & GNU_PROPERTY_X86_FEATURE_1_SHSTK) != 0); > if (enable_shstk != shstk_enabled) > { > found_shstk_legacy = true; Ok. > diff --git a/sysdeps/x86/dl-prop.h b/sysdeps/x86/dl-prop.h > index 89911e19e2..61c0624c09 100644 > --- a/sysdeps/x86/dl-prop.h > +++ b/sysdeps/x86/dl-prop.h > @@ -19,14 +19,54 @@ > #ifndef _DL_PROP_H > #define _DL_PROP_H > > +#include > + > extern void _dl_cet_check (struct link_map *, const char *) > attribute_hidden; > extern void _dl_cet_open_check (struct link_map *) > attribute_hidden; > > +static void > +dl_isa_level_check (struct link_map *m, const char *program) > +{ > + const struct cpu_features *cpu_features = __get_cpu_features (); > + unsigned int i; > + struct link_map *l; > + > + i = m->l_searchlist.r_nlist; > + while (i-- > 0) > + { > + /* Check each shared object to see if ISA level is compatible. */ > + l = m->l_initfini[i]; > + > + /* Skip ISA level check if functions have been executed. */ > + if (l->l_init_called) > + continue; > + > +#ifdef SHARED > + /* Skip ISA level check for ld.so since ld.so won't run if its ISA > + level is higher than CPU. */ > + if (l == &GL(dl_rtld_map) || l->l_real == &GL(dl_rtld_map)) > + continue; > +#endif > + > + if ((l->l_x86_isa_1_needed & cpu_features->isa_1) > + != l->l_x86_isa_1_needed) > + { > + if (program) > + _dl_fatal_printf ("%s: CPU ISA level is lower than required\n", > + *l->l_name != '\0' ? l->l_name : program); > + else > + _dl_signal_error (0, l->l_name, "dlopen", > + N_("CPU ISA level is lower than required")); > + } > + } > +} > + Ok. Not sure if it is worth to translate the _dl_fatal_printf (it seems that at least one use at elf/dl-open.c does it). > static inline void __attribute__ ((always_inline)) > _rtld_main_check (struct link_map *m, const char *program) > { > + dl_isa_level_check (m, program); > #if CET_ENABLED > _dl_cet_check (m, program); > #endif > @@ -35,20 +75,18 @@ _rtld_main_check (struct link_map *m, const char *program) > static inline void __attribute__ ((always_inline)) > _dl_open_check (struct link_map *m) > { > + dl_isa_level_check (m, NULL); > #if CET_ENABLED > _dl_cet_open_check (m); > #endif > } > Ok. > static inline void __attribute__ ((unused)) > -_dl_process_cet_property_note (struct link_map *l, > - const ElfW(Nhdr) *note, > - const ElfW(Addr) size, > - const ElfW(Addr) align) > +_dl_process_property_note (struct link_map *l, const ElfW(Nhdr) *note, > + const ElfW(Addr) size, const ElfW(Addr) align) > { > -#if CET_ENABLED > /* Skip if we have seen a NT_GNU_PROPERTY_TYPE_0 note before. */ > - if (l->l_cet != lc_unknown) > + if (l->l_property != lc_property_unknown) > return; > > /* The NT_GNU_PROPERTY_TYPE_0 note must be aliged to 4 bytes in Ok. > @@ -59,7 +97,8 @@ _dl_process_cet_property_note (struct link_map *l, > > const ElfW(Addr) start = (ElfW(Addr)) note; > > - unsigned int feature_1 = 0; > + unsigned int feature_1_and = 0; > + unsigned int isa_1_needed = 0; > unsigned int last_type = 0; > > while ((ElfW(Addr)) (note + 1) - start < size) > @@ -71,11 +110,11 @@ _dl_process_cet_property_note (struct link_map *l, > { > /* Stop if we see more than one GNU property note which may > be generated by the older linker. */ > - if (l->l_cet != lc_unknown) > + if (l->l_property != lc_property_unknown) > return; > > - /* Check CET status now. */ > - l->l_cet = lc_none; > + /* Check CET status and ISA levels now. */ > + l->l_property = lc_property_none; > > /* Check for invalid property. */ > if (note->n_descsz < 8 Ok. > @@ -101,26 +140,37 @@ _dl_process_cet_property_note (struct link_map *l, > > last_type = type; > > - if (type == GNU_PROPERTY_X86_FEATURE_1_AND) > + if (type == GNU_PROPERTY_X86_FEATURE_1_AND > + || type == GNU_PROPERTY_X86_ISA_1_NEEDED) > { > - /* The size of GNU_PROPERTY_X86_FEATURE_1_AND is 4 > - bytes. When seeing GNU_PROPERTY_X86_FEATURE_1_AND, > - we stop the search regardless if its size is correct > - or not. There is no point to continue if this note > - is ill-formed. */ > + /* The sizes of types which we are searching for are > + 4 bytes. There is no point to continue if this > + note is ill-formed. */ > if (datasz != 4) > return; > Ok. > - feature_1 = *(unsigned int *) ptr; > - > - /* Keep searching for the next GNU property note > - generated by the older linker. */ > - break; > + /* NB: Stop the scan only after seeing all types which > + we are searching for. */ > + _Static_assert ((GNU_PROPERTY_X86_ISA_1_NEEDED > > + GNU_PROPERTY_X86_FEATURE_1_AND), > + "GNU_PROPERTY_X86_ISA_1_NEEDED > " > + "GNU_PROPERTY_X86_FEATURE_1_AND"); Ok. > + if (type == GNU_PROPERTY_X86_FEATURE_1_AND) > + feature_1_and = *(unsigned int *) ptr; > + else > + { > + isa_1_needed = *(unsigned int *) ptr; > + > + /* Keep searching for the next GNU property note > + generated by the older linker. */ > + break; > + } > } > - else if (type > GNU_PROPERTY_X86_FEATURE_1_AND) > + else if (type > GNU_PROPERTY_X86_ISA_1_NEEDED) > { > - /* Stop since property type is in ascending order. */ > - return; > + /* Stop the scan since property type is in ascending > + order. */ > + break; > } > > /* Check the next property item. */ Ok. > @@ -137,18 +187,21 @@ _dl_process_cet_property_note (struct link_map *l, > } > > /* We get here only if there is one or no GNU property note. */ > - if ((feature_1 & GNU_PROPERTY_X86_FEATURE_1_IBT)) > - l->l_cet |= lc_ibt; > - if ((feature_1 & GNU_PROPERTY_X86_FEATURE_1_SHSTK)) > - l->l_cet |= lc_shstk; > -#endif > + if (isa_1_needed || feature_1_and) No implicit checks. > + { > + l->l_property = lc_property_valid; > + l->l_x86_isa_1_needed = isa_1_needed; > + l->l_x86_feature_1_and = feature_1_and; > + } > + else > + l->l_property = lc_property_none; > } > > static inline void __attribute__ ((unused)) > _dl_process_pt_note (struct link_map *l, const ElfW(Phdr) *ph) > { > const ElfW(Nhdr) *note = (const void *) (ph->p_vaddr + l->l_addr); > - _dl_process_cet_property_note (l, note, ph->p_memsz, ph->p_align); > + _dl_process_property_note (l, note, ph->p_memsz, ph->p_align); > } > > static inline int __attribute__ ((always_inline)) Ok. > diff --git a/sysdeps/x86/get-isa-level.h b/sysdeps/x86/get-isa-level.h > new file mode 100644 > index 0000000000..166dd5df01 > --- /dev/null > +++ b/sysdeps/x86/get-isa-level.h > @@ -0,0 +1,66 @@ > +/* Get x86 ISA level. > + This file is part of the GNU C Library. > + Copyright (C) 2020 Free Software Foundation, Inc. > + > + The GNU C Library is free software; you can redistribute it and/or > + modify it under the terms of the GNU Lesser General Public > + License as published by the Free Software Foundation; either > + version 2.1 of the License, or (at your option) any later version. > + > + The GNU C Library is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + Lesser General Public License for more details. > + > + You should have received a copy of the GNU Lesser General Public > + License along with the GNU C Library; if not, see > + . */ > + > +#include > + > +/* Get GNU_PROPERTY_X86_ISA_1_BASELINE and GNU_PROPERTY_X86_ISA_1_V[234] > + ISA level. */ > + > +static unsigned int > +get_isa_level (const struct cpu_features *cpu_features) > +{ > + unsigned isa_level = 0; s/unsigned/unsigned int/ > + > + if (CPU_FEATURE_USABLE_P (cpu_features, CMOV) > + && CPU_FEATURE_USABLE_P (cpu_features, CX8) > + && CPU_FEATURE_CPU_P (cpu_features, FPU) > + && CPU_FEATURE_USABLE_P (cpu_features, FXSR) > + && CPU_FEATURE_USABLE_P (cpu_features, MMX) > + && CPU_FEATURE_USABLE_P (cpu_features, SSE) > + && CPU_FEATURE_USABLE_P (cpu_features, SSE2)) > + { > + isa_level = GNU_PROPERTY_X86_ISA_1_BASELINE; > + if (CPU_FEATURE_USABLE_P (cpu_features, CMPXCHG16B) > + && CPU_FEATURE_USABLE_P (cpu_features, LAHF64_SAHF64) > + && CPU_FEATURE_USABLE_P (cpu_features, POPCNT) > + && CPU_FEATURE_USABLE_P (cpu_features, SSE3) > + && CPU_FEATURE_USABLE_P (cpu_features, SSSE3) > + && CPU_FEATURE_USABLE_P (cpu_features, SSE4_1) > + && CPU_FEATURE_USABLE_P (cpu_features, SSE4_2)) > + { > + isa_level |= GNU_PROPERTY_X86_ISA_1_V2; > + if (CPU_FEATURE_USABLE_P (cpu_features, AVX) > + && CPU_FEATURE_USABLE_P (cpu_features, AVX2) > + && CPU_FEATURE_USABLE_P (cpu_features, F16C) > + && CPU_FEATURE_USABLE_P (cpu_features, FMA) > + && CPU_FEATURE_USABLE_P (cpu_features, LZCNT) > + && CPU_FEATURE_USABLE_P (cpu_features, MOVBE)) > + { > + isa_level |= GNU_PROPERTY_X86_ISA_1_V3; > + if (CPU_FEATURE_USABLE_P (cpu_features, AVX512F) > + && CPU_FEATURE_USABLE_P (cpu_features, AVX512BW) > + && CPU_FEATURE_USABLE_P (cpu_features, AVX512CD) > + && CPU_FEATURE_USABLE_P (cpu_features, AVX512DQ) > + && CPU_FEATURE_USABLE_P (cpu_features, AVX512VL)) > + isa_level |= GNU_PROPERTY_X86_ISA_1_V4; > + } > + } > + } > + > + return isa_level; > +} Do we actually support a isa level lower than baseline? > diff --git a/sysdeps/x86/include/cpu-features.h b/sysdeps/x86/include/cpu-features.h > index f62be0b9b3..ef0c6b4fbc 100644 > --- a/sysdeps/x86/include/cpu-features.h > +++ b/sysdeps/x86/include/cpu-features.h > @@ -129,6 +129,8 @@ struct cpu_features > struct cpu_features_basic basic; > struct cpuid_features features[COMMON_CPUID_INDEX_MAX]; > unsigned int preferred[PREFERRED_FEATURE_INDEX_MAX]; > + /* X86 micro-architecture ISA levels. */ > + unsigned int isa_1; > /* The state size for XSAVEC or XSAVE. The type must be unsigned long > int so that we use > Ok. > diff --git a/sysdeps/x86/isa-level.c b/sysdeps/x86/isa-level.c > new file mode 100644 > index 0000000000..0751e86f27 > --- /dev/null > +++ b/sysdeps/x86/isa-level.c > @@ -0,0 +1,95 @@ > +/* ELF program property for x86 ISA level. > + Copyright (C) 2020 Free Software Foundation, Inc. > + This file is part of the GNU C Library. > + > + The GNU C Library is free software; you can redistribute it and/or > + modify it under the terms of the GNU Lesser General Public > + License as published by the Free Software Foundation; either > + version 2.1 of the License, or (at your option) any later version. > + > + In addition to the permissions in the GNU Lesser General Public > + License, the Free Software Foundation gives you unlimited > + permission to link the compiled version of this file with other > + programs, and to distribute those programs without any restriction > + coming from the use of this file. (The Lesser General Public > + License restrictions do apply in other respects; for example, they > + cover modification of the file, and distribution when not linked > + into another program.) > + > + The GNU C Library is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + Lesser General Public License for more details. > + > + You should have received a copy of the GNU Lesser General Public > + License along with the GNU C Library; if not, see > + . */ > + > +#include > + > +/* ELF program property for x86 ISA level. */ > +#ifdef INCLUDE_X86_ISA_LEVEL > +# if defined __x86_64__ || defined __FXSR__ || !defined _SOFT_FLOAT \ > + || defined __MMX__ || defined __SSE__ || defined __SSE2__ > +# define ISA_BASELINE GNU_PROPERTY_X86_ISA_1_BASELINE > +# else > +# define ISA_BASELINE 0 > +# endif > + > +# if defined __GCC_HAVE_SYNC_COMPARE_AND_SWAP_16 \ > + || (defined __x86_64__ && defined __LAHF_SAHF__) \ > + || defined __POPCNT__ || defined __SSE3__ \ > + || defined __SSSE3__ || defined __SSE4_1__ || defined __SSE4_2__ > +# define ISA_V2 GNU_PROPERTY_X86_ISA_1_V2 > +# else > +# define ISA_V2 0 > +# endif > + > +# if defined __AVX__ || defined __AVX2__ || defined __F16C__ \ > + || defined __FMA__ || defined __LZCNT__ || defined __MOVBE__ \ > + || defined __XSAVE__ > +# define ISA_V3 GNU_PROPERTY_X86_ISA_1_V3 > +# else > +# define ISA_V3 0 > +# endif > + > +# if defined __AVX512F__ || defined __AVX512BW__ || defined __AVX512CD__ \ > + || defined __AVX512DQ__ || defined __AVX512VL__ > +# define ISA_V4 GNU_PROPERTY_X86_ISA_1_V4 > +# else > +# define ISA_V4 0 > +# endif > + > +# define ISA_LEVEL (ISA_BASELINE | ISA_V2 | ISA_V3 | ISA_V4) > + > +# if ISA_LEVEL > +# ifdef __LP64__ > +# define PROPERTY_ALIGN 3 > +# else > +# define PROPERTY_ALIGN 2 > +# endif > + > +# define note_stringify(arg) note_stringify_1(arg) > +# define note_stringify_1(arg) #arg > + > +asm(".pushsection \".note.gnu.property\",\"a\",@note\n" > +" .p2align " note_stringify (PROPERTY_ALIGN) > + /* name length. */ > +"\n .long 1f - 0f\n" > + /* data length. */ > +" .long 4f - 1f\n" > + /* note type: NT_GNU_PROPERTY_TYPE_0. */ > +" .long " note_stringify (NT_GNU_PROPERTY_TYPE_0) > + /* vendor name. */ > +"\n0: .asciz \"GNU\"\n" > +"1: .p2align " note_stringify (PROPERTY_ALIGN) > + /* pr_type: GNU_PROPERTY_X86_ISA_1_NEEDED. */ > +"\n .long " note_stringify (GNU_PROPERTY_X86_ISA_1_NEEDED) > + /* pr_datasz. */ > +"\n .long 3f - 2f\n" > + /* GNU_PROPERTY_X86_ISA_1_V[234]. */ > +"2:\n .long " note_stringify (ISA_LEVEL) > +"\n3:\n .p2align " note_stringify (PROPERTY_ALIGN) > +"\n4:\n .popsection"); > +# endif /* ISA_LEVEL */ > +#endif /* INCLUDE_X86_ISA_LEVEL */ Ok. > diff --git a/sysdeps/x86/link_map.h b/sysdeps/x86/link_map.h > index 2e4f8850f9..3c550e529a 100644 > --- a/sysdeps/x86/link_map.h > +++ b/sysdeps/x86/link_map.h > @@ -16,12 +16,16 @@ > License along with the GNU C Library; if not, see > . */ > > -/* If this object is enabled with CET. */ > +/* if this object has GNU property. */ > enum > { > - lc_unknown = 0, /* Unknown CET status. */ > - lc_none = 1 << 0, /* Not enabled with CET. */ > - lc_ibt = 1 << 1, /* Enabled with IBT. */ > - lc_shstk = 1 << 2, /* Enabled with STSHK. */ > - lc_ibt_and_shstk = lc_ibt | lc_shstk /* Enabled with both. */ > - } l_cet:3; > + lc_property_unknown = 0, /* Unknown property status. */ > + lc_property_none = 1 << 0, /* No property. */ > + lc_property_valid = 1 << 1 /* Has valid property. */ > + } l_property:2; > + Ok. > +/* GNU_PROPERTY_X86_FEATURE_1_AND of this object. */ > +unsigned int l_x86_feature_1_and; > + > +/* GNU_PROPERTY_X86_ISA_1_NEEDED of this object. */ > +unsigned int l_x86_isa_1_needed; Ok. > diff --git a/sysdeps/x86/tst-isa-level-1.c b/sysdeps/x86/tst-isa-level-1.c > new file mode 100644 > index 0000000000..c263157c8c > --- /dev/null > +++ b/sysdeps/x86/tst-isa-level-1.c > @@ -0,0 +1,74 @@ > +/* Check ISA level on dlopened shared object. > + Copyright (C) 2020 Free Software Foundation, Inc. > + This file is part of the GNU C Library. > + > + The GNU C Library is free software; you can redistribute it and/or > + modify it under the terms of the GNU Lesser General Public > + License as published by the Free Software Foundation; either > + version 2.1 of the License, or (at your option) any later version. > + > + The GNU C Library is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + Lesser General Public License for more details. > + > + You should have received a copy of the GNU Lesser General Public > + License along with the GNU C Library; if not, see > + . */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +static void > +do_test_1 (const char *modname, bool fail) > +{ > + int (*fp) (void); > + void *h; > + > + h = dlopen (modname, RTLD_LAZY); > + if (h == NULL) > + { > + const char *err = dlerror (); > + if (fail) > + { > + if (strstr (err, "CPU ISA level is lower than required") == NULL) > + FAIL_EXIT1 ("incorrect dlopen '%s' error: %s\n", modname, err); > + > + return; > + } > + > + FAIL_EXIT1 ("cannot open '%s': %s\n", modname, err); > + } > + > + if (fail) > + FAIL_EXIT1 ("dlopen '%s' should have failed\n", modname); > + > + fp = xdlsym (h, "test"); > + > + if (fp () != 0) > + FAIL_EXIT1 ("test () != 0\n"); > + > + dlclose (h); > +} > + Ok. > +static int > +do_test (void) > +{ > + const struct cpu_features *cpu_features > + = __x86_get_cpu_features (COMMON_CPUID_INDEX_MAX); > + unsigned int isa_level = get_isa_level (cpu_features); > + /* Skip on x86-64-v4 platforms since dlopen always works. */ > + if ((isa_level & GNU_PROPERTY_X86_ISA_1_V4) != 0) > + return EXIT_UNSUPPORTED; > + do_test_1 ("tst-isa-level-mod-1a.so", true); > + do_test_1 ("tst-isa-level-mod-1b.so", false); > + return EXIT_SUCCESS; > +} > + > +#include Maybe use my suggestion to improve test coverage. > diff --git a/sysdeps/x86/tst-isa-level-mod-1.c b/sysdeps/x86/tst-isa-level-mod-1.c > new file mode 100644 > index 0000000000..3816536428 > --- /dev/null > +++ b/sysdeps/x86/tst-isa-level-mod-1.c > @@ -0,0 +1,23 @@ > +/* Check ISA level on dlopened shared object. > + Copyright (C) 2019-2020 Free Software Foundation, Inc. > + This file is part of the GNU C Library. > + > + The GNU C Library is free software; you can redistribute it and/or > + modify it under the terms of the GNU Lesser General Public > + License as published by the Free Software Foundation; either > + version 2.1 of the License, or (at your option) any later version. > + > + The GNU C Library is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + Lesser General Public License for more details. > + > + You should have received a copy of the GNU Lesser General Public > + License along with the GNU C Library; if not, see > + . */ > + > +int > +test (void) > +{ > + return 0; > +} Ok. > diff --git a/sysdeps/x86/tst-isa-level-mod-1a.c b/sysdeps/x86/tst-isa-level-mod-1a.c > new file mode 100644 > index 0000000000..4f026dd915 > --- /dev/null > +++ b/sysdeps/x86/tst-isa-level-mod-1a.c > @@ -0,0 +1,2 @@ > +#include > +#include "tst-isa-level-mod-1.c" > diff --git a/sysdeps/x86/tst-isa-level-mod-1b.c b/sysdeps/x86/tst-isa-level-mod-1b.c > new file mode 100644 > index 0000000000..d6fe0685a4 > --- /dev/null > +++ b/sysdeps/x86/tst-isa-level-mod-1b.c > @@ -0,0 +1 @@ > +#include "tst-isa-level-mod-1.c" Ok. > diff --git a/sysdeps/x86_64/dl-hwcaps-subdirs.c b/sysdeps/x86_64/dl-hwcaps-subdirs.c > index 8810a822ef..e5640303f9 100644 > --- a/sysdeps/x86_64/dl-hwcaps-subdirs.c > +++ b/sysdeps/x86_64/dl-hwcaps-subdirs.c > @@ -18,6 +18,7 @@ > > #include > #include > +#include > > const char _dl_hwcaps_subdirs[] = "x86-64-v4:x86-64-v3:x86-64-v2"; > enum { subdirs_count = 3 }; /* Number of components in _dl_hwcaps_subdirs. */ > @@ -25,40 +26,25 @@ enum { subdirs_count = 3 }; /* Number of components in _dl_hwcaps_subdirs. */ > uint32_t > _dl_hwcaps_subdirs_active (void) > { > + const struct cpu_features *cpu_features > + = __x86_get_cpu_features (COMMON_CPUID_INDEX_MAX); > + unsigned int isa_level = get_isa_level (cpu_features); > int active = 0; > > /* Test in reverse preference order. */ > > /* x86-64-v2. */ > - if (!(CPU_FEATURE_USABLE (CMPXCHG16B) > - && CPU_FEATURE_USABLE (LAHF64_SAHF64) > - && CPU_FEATURE_USABLE (POPCNT) > - && CPU_FEATURE_USABLE (SSE3) > - && CPU_FEATURE_USABLE (SSE4_1) > - && CPU_FEATURE_USABLE (SSE4_2) > - && CPU_FEATURE_USABLE (SSSE3))) > + if (!(isa_level & GNU_PROPERTY_X86_ISA_1_V2)) > return _dl_hwcaps_subdirs_build_bitmask (subdirs_count, active); > ++active; > > /* x86-64-v3. */ > - if (!(CPU_FEATURE_USABLE (AVX) > - && CPU_FEATURE_USABLE (AVX2) > - && CPU_FEATURE_USABLE (BMI1) > - && CPU_FEATURE_USABLE (BMI2) > - && CPU_FEATURE_USABLE (F16C) > - && CPU_FEATURE_USABLE (FMA) > - && CPU_FEATURE_USABLE (LZCNT) > - && CPU_FEATURE_USABLE (MOVBE) > - && CPU_FEATURE_USABLE (OSXSAVE))) > + if (!(isa_level & GNU_PROPERTY_X86_ISA_1_V3)) > return _dl_hwcaps_subdirs_build_bitmask (subdirs_count, active); > ++active; > > - /* x86-64-v4. */ > - if (!(CPU_FEATURE_USABLE (AVX512F) > - && CPU_FEATURE_USABLE (AVX512BW) > - && CPU_FEATURE_USABLE (AVX512CD) > - && CPU_FEATURE_USABLE (AVX512DQ) > - && CPU_FEATURE_USABLE (AVX512VL))) > + /* x86-64-v4. */ > + if (!(isa_level & GNU_PROPERTY_X86_ISA_1_V4)) > return _dl_hwcaps_subdirs_build_bitmask (subdirs_count, active); > ++active; > Ok. > diff --git a/sysdeps/x86_64/tst-glibc-hwcaps.c b/sysdeps/x86_64/tst-glibc-hwcaps.c > index 3075a8286d..a041a9047d 100644 > --- a/sysdeps/x86_64/tst-glibc-hwcaps.c > +++ b/sysdeps/x86_64/tst-glibc-hwcaps.c > @@ -19,7 +19,8 @@ > #include > #include > #include > -#include > +#include > +#include > > extern int marker2 (void); > extern int marker3 (void); > @@ -31,35 +32,15 @@ compute_level (void) > { > const struct cpu_features *cpu_features > = __x86_get_cpu_features (COMMON_CPUID_INDEX_MAX); > - > - if (!(CPU_FEATURE_USABLE_P (cpu_features, CMPXCHG16B) > - && CPU_FEATURE_USABLE_P (cpu_features, LAHF64_SAHF64) > - && CPU_FEATURE_USABLE_P (cpu_features, POPCNT) > - && CPU_FEATURE_USABLE_P (cpu_features, MMX) > - && CPU_FEATURE_USABLE_P (cpu_features, SSE) > - && CPU_FEATURE_USABLE_P (cpu_features, SSE2) > - && CPU_FEATURE_USABLE_P (cpu_features, SSE3) > - && CPU_FEATURE_USABLE_P (cpu_features, SSSE3) > - && CPU_FEATURE_USABLE_P (cpu_features, SSE4_1) > - && CPU_FEATURE_USABLE_P (cpu_features, SSE4_2))) > - return 1; > - if (!(CPU_FEATURE_USABLE_P (cpu_features, AVX) > - && CPU_FEATURE_USABLE_P (cpu_features, AVX2) > - && CPU_FEATURE_USABLE_P (cpu_features, BMI1) > - && CPU_FEATURE_USABLE_P (cpu_features, BMI2) > - && CPU_FEATURE_USABLE_P (cpu_features, F16C) > - && CPU_FEATURE_USABLE_P (cpu_features, FMA) > - && CPU_FEATURE_USABLE_P (cpu_features, LZCNT) > - && CPU_FEATURE_USABLE_P (cpu_features, MOVBE) > - && CPU_FEATURE_USABLE_P (cpu_features, OSXSAVE))) > - return 2; > - if (!(CPU_FEATURE_USABLE_P (cpu_features, AVX512F) > - && CPU_FEATURE_USABLE_P (cpu_features, AVX512BW) > - && CPU_FEATURE_USABLE_P (cpu_features, AVX512CD) > - && CPU_FEATURE_USABLE_P (cpu_features, AVX512DQ) > - && CPU_FEATURE_USABLE_P (cpu_features, AVX512VL))) > - return 3; > - return 4; > + unsigned int isa_level = get_isa_level (cpu_features); > + > + if (!(isa_level & GNU_PROPERTY_X86_ISA_1_V2)) > + return 1; > + if (!(isa_level & GNU_PROPERTY_X86_ISA_1_V3)) > + return 2; > + if (!(isa_level & GNU_PROPERTY_X86_ISA_1_V4)) > + return 3; > + return 4; > } > > static int > Ok.