Message ID | 703f911ba1d0d946e4978830e5d3161674bfc77c.1642179009.git.fweimer@redhat.com |
---|---|
State | New |
Headers | show |
Series | Reliable CPU compatibility diagnostics in ld.so | expand |
On Fri, Jan 14, 2022 at 8:53 AM Florian Weimer <fweimer@redhat.com> wrote: > > This ISA level covers the glibc build itself. <dl-hwcap-check.h> > cannot be used because this check (by design) happens before > DL_PLATFORM_INIT and the x86 CPU flags initialization. > --- > v2: Reflect renamed Makefile variable. > sysdeps/x86/Makefile | 1 + > sysdeps/x86/dl-get-cpu-features.c | 31 ++++++++++++++++++++++++++++++- > 2 files changed, 31 insertions(+), 1 deletion(-) > > diff --git a/sysdeps/x86/Makefile b/sysdeps/x86/Makefile > index 402986ff68..6cf708335c 100644 > --- a/sysdeps/x86/Makefile > +++ b/sysdeps/x86/Makefile > @@ -7,6 +7,7 @@ sysdep_routines += get-cpuid-feature-leaf > sysdep-dl-routines += dl-get-cpu-features > sysdep_headers += sys/platform/x86.h bits/platform/x86.h > > +CFLAGS-dl-get-cpu-features.os += $(rtld-early-cflags) > CFLAGS-get-cpuid-feature-leaf.o += $(no-stack-protector) > > tests += tst-get-cpu-features tst-get-cpu-features-static \ > diff --git a/sysdeps/x86/dl-get-cpu-features.c b/sysdeps/x86/dl-get-cpu-features.c > index 6339c9df4e..4ec0e5d2af 100644 > --- a/sysdeps/x86/dl-get-cpu-features.c > +++ b/sysdeps/x86/dl-get-cpu-features.c > @@ -20,6 +20,7 @@ > > #ifdef SHARED > # include <cpu-features.c> > +# include <gcc-macros.h> > > /* NB: Normally, DL_PLATFORM_INIT calls init_cpu_features to initialize > CPU features in dynamic executable. But when loading ld.so inside of > @@ -36,7 +37,35 @@ _dl_x86_init_cpu_features (void) > { > struct cpu_features *cpu_features = __get_cpu_features (); > if (cpu_features->basic.kind == arch_kind_unknown) > - init_cpu_features (cpu_features); > + { > + init_cpu_features (cpu_features); > + > +# if IS_IN (rtld) > + /* See isa-level.c. */ > +# if defined GCCMACRO__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16 \ > + && defined HAVE_X86_LAHF_SAHF && defined GCCMACRO__POPCNT__ \ > + && defined GCCMACRO__SSE3__ && defined GCCMACRO__SSSE3__ \ > + && defined GCCMACRO__SSE4_1__ && defined GCCMACRO__SSE4_2__ > + if (!(cpu_features->isa_1 & GNU_PROPERTY_X86_ISA_1_V2)) > + _dl_fatal_printf ("\ > +Fatal glibc error: CPU does not support x86-64-v%d\n", 2); > +# if defined GCCMACRO__AVX__ && defined GCCMACRO__AVX2__ \ > + && defined GCCMACRO__F16C__ && defined GCCMACRO__FMA__ \ > + && defined GCCMACRO__LZCNT__ && defined HAVE_X86_MOVBE > + if (!(cpu_features->isa_1 & GNU_PROPERTY_X86_ISA_1_V3)) > + _dl_fatal_printf ("\ > +Fatal glibc error: CPU does not support x86-64-v%d\n", 3); > +# if defined GCCMACRO__AVX512F__ && defined GCCMACRO__AVX512BW__ \ > + && defined GCCMACRO__AVX512CD__ && defined GCCMACRO__AVX512DQ__ \ > + && defined GCCMACRO__AVX512VL__ > + if (!(cpu_features->isa_1 & GNU_PROPERTY_X86_ISA_1_V4)) > + _dl_fatal_printf ("\ > +Fatal glibc error: CPU does not support x86-64-v%d\n", 4); > +# endif /* ISA level 4 */ > +# endif /* ISA level 3 */ > +# endif /* ISA level 2 */ > +# endif /* IS_IN (rtld) */ > + } > } > > __ifunc (__x86_cpu_features, __x86_cpu_features, NULL, void, > -- > 2.34.1 > > LGTM. Reviewed-by: H.J. Lu <hjl.tools@gmail.com> Thanks.
diff --git a/sysdeps/x86/Makefile b/sysdeps/x86/Makefile index 402986ff68..6cf708335c 100644 --- a/sysdeps/x86/Makefile +++ b/sysdeps/x86/Makefile @@ -7,6 +7,7 @@ sysdep_routines += get-cpuid-feature-leaf sysdep-dl-routines += dl-get-cpu-features sysdep_headers += sys/platform/x86.h bits/platform/x86.h +CFLAGS-dl-get-cpu-features.os += $(rtld-early-cflags) CFLAGS-get-cpuid-feature-leaf.o += $(no-stack-protector) tests += tst-get-cpu-features tst-get-cpu-features-static \ diff --git a/sysdeps/x86/dl-get-cpu-features.c b/sysdeps/x86/dl-get-cpu-features.c index 6339c9df4e..4ec0e5d2af 100644 --- a/sysdeps/x86/dl-get-cpu-features.c +++ b/sysdeps/x86/dl-get-cpu-features.c @@ -20,6 +20,7 @@ #ifdef SHARED # include <cpu-features.c> +# include <gcc-macros.h> /* NB: Normally, DL_PLATFORM_INIT calls init_cpu_features to initialize CPU features in dynamic executable. But when loading ld.so inside of @@ -36,7 +37,35 @@ _dl_x86_init_cpu_features (void) { struct cpu_features *cpu_features = __get_cpu_features (); if (cpu_features->basic.kind == arch_kind_unknown) - init_cpu_features (cpu_features); + { + init_cpu_features (cpu_features); + +# if IS_IN (rtld) + /* See isa-level.c. */ +# if defined GCCMACRO__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16 \ + && defined HAVE_X86_LAHF_SAHF && defined GCCMACRO__POPCNT__ \ + && defined GCCMACRO__SSE3__ && defined GCCMACRO__SSSE3__ \ + && defined GCCMACRO__SSE4_1__ && defined GCCMACRO__SSE4_2__ + if (!(cpu_features->isa_1 & GNU_PROPERTY_X86_ISA_1_V2)) + _dl_fatal_printf ("\ +Fatal glibc error: CPU does not support x86-64-v%d\n", 2); +# if defined GCCMACRO__AVX__ && defined GCCMACRO__AVX2__ \ + && defined GCCMACRO__F16C__ && defined GCCMACRO__FMA__ \ + && defined GCCMACRO__LZCNT__ && defined HAVE_X86_MOVBE + if (!(cpu_features->isa_1 & GNU_PROPERTY_X86_ISA_1_V3)) + _dl_fatal_printf ("\ +Fatal glibc error: CPU does not support x86-64-v%d\n", 3); +# if defined GCCMACRO__AVX512F__ && defined GCCMACRO__AVX512BW__ \ + && defined GCCMACRO__AVX512CD__ && defined GCCMACRO__AVX512DQ__ \ + && defined GCCMACRO__AVX512VL__ + if (!(cpu_features->isa_1 & GNU_PROPERTY_X86_ISA_1_V4)) + _dl_fatal_printf ("\ +Fatal glibc error: CPU does not support x86-64-v%d\n", 4); +# endif /* ISA level 4 */ +# endif /* ISA level 3 */ +# endif /* ISA level 2 */ +# endif /* IS_IN (rtld) */ + } } __ifunc (__x86_cpu_features, __x86_cpu_features, NULL, void,