AVX instructions leak outside of CPU feature check and cause SIGILL
@thiago
Submitted by Thiago Macieira Assigned to Alok Hota @ahota
Link to original bug (#108135)
Description
Reported at https://github.com/clearlinux/distribution/issues/210
Symptom: when running certain applications (Xwayland in our case) on an Atom CPU, the application crashes with SIGILL. The backtrace:
#7 (closed) _Z41__static_initialization_and_destruction_0ii.constprop.120() - [swrast_dri.so] - lower_x86.cpp:73 #8 (closed) _GLOBAL__I_65535_0_gallium_dri_la_target.o.1657199() - [swrast_dri.so] #9 (closed) call_init.part.0() - [ld-linux-x86-64.so.2] - dl-init.c:72 #10 (closed) _dl_init() - [ld-linux-x86-64.so.2] - dl-init.c:30 #11 (closed) dl_open_worker() - [ld-linux-x86-64.so.2] - dl-open.c:506 #12 (closed) _dl_catch_exception() - [libc.so.6] - dl-error-skeleton.c:196 #13 (closed) _dl_open() - [ld-linux-x86-64.so.2] - dl-open.c:588 #14 dlopen_doit() - [libdl.so.2] - dlopen.c:66 #15 (closed) _dl_catch_exception() - [libc.so.6] - dl-error-skeleton.c:196 #16 _dl_catch_error() - [libc.so.6] - dl-error-skeleton.c:215 #17 (closed) _dlerror_run() - [libdl.so.2] - dlerror.c:163 #18 dlopen@@GLIBC_2.2.5() - [libdl.so.2] - dlopen.c:87 #19 (closed) glxProbeDriver() - [/usr/bin/Xwayland] - glxdricommon.c:305 #20 (closed) __glXDRIscreenProbe() - [/usr/bin/Xwayland] - glxdriswrast.c:437 #21 (closed) xorgGlxServerInit() - [/usr/bin/Xwayland] - glxext.c:550 #22 (closed) _CallCallbacks() - [/usr/bin/Xwayland] - dixutils.c:737 #23 (closed) GlxExtensionInit() - [/usr/bin/Xwayland] - callback.h:83 #24 (closed) InitExtensions() - [/usr/bin/Xwayland] - miinitext.c:267 #25 dix_main() - [/usr/bin/Xwayland] - main.c:197 #26 (closed) __libc_start_main() - [libc.so.6] - libc-start.c:308 #27 (closed) _start() - [/usr/bin/Xwayland] - start.S:120
Investigation shows that the swrast_dri.so plugin contains AVX instructions outside of a CPUID check in the "__static_initialization_and_destruction_0" function. Further investigation shows some of those functions come from src/gallium/drivers/swr/rasterizer/jitter/functionpasses/lower_x86.cpp, while initialising the variable SwrJit::instructionMap (which is a global static non-POD of type std::map - see https://gitlab.freedesktop.org/mesa/mesa/blob/master/src/gallium/drivers/swr/rasterizer/jitter/functionpasses/lower_x86.cpp#L66).
This lower_x86.cpp file is compiled with -mavx. This means the compiler is free to generate AVX instructions anywhere in the file without a CPUID check, including in the dynamic initialisation and destruction code that the std::map variable requires.
The simplest solution I can think of, for this particular instruction, is to change it from a global static to a local static. This will solve the problem for this particular initialisation, but I think there are more variables with this problem.
Version: git