linuxx86-64illegal-instruction

Why do I get an illegal instruction using __builtin_ia32_wrfsbase64 when skylake has fsgsbase?


I'm running my code on a server with "Intel Xeon Processor (Skylake, IBRS)". I listed the cpu flags at the bottom. I got a core dump, ran it in gdb and saw the illegal instruction was __builtin_ia32_wrfsbase64 (I call the intrinsic _writefsbase_u64). __builtin_ia32_rdfsbase64 also causes the illegal instruction. It supports the fsgsbase flag so I don't know why I'm getting a problem

flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 syscall nx pdpe1gb rdtscp lm constant_tsc rep_good nopl xtopology cpuid tsc_known_freq pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm cpuid_fault invpcid_single pti ssbd ibrs ibpb fsgsbase bmi1 hle avx2 smep bmi2 erms invpcid rtm avx512f avx512dq clwb avx512cd avx512bw avx512vl xsaveopt arat pku ospke


Solution

  • The FSGSBASE instructions require support from the operating system as well as the hardware. The OS has to be aware that the base registers could be changed by user code without informing the OS; older OSes might have assumed that the registers could only be changed when the user made an explicit system call. There is a bit in CR4 that determines whether unprivileged code is allowed to execute these instructions, and by default, it is unset. The idea is that only an OS that contains the appropriate support will enable this bit. See Intel's guidelines for more details.

    In Linux, this support was added in kernel version 5.9 (changelog). Per your comment, you are using an older kernel, so you cannot use these instructions, and must fall back to using the arch_prctl system call to request an update to the FS or GS base registers. Or else upgrade your kernel / OS.

    There is a bit in the ELF AUX vector that your program can test at runtime to determine whether the FSGSBASE instructions are usable. See https://www.kernel.org/doc/html/latest/x86/x86_64/fsgs.html under "FSGSBASE instructions enablement".