Blame sysdeps/x86/cpu-features.c

Packit 6c4009
/* Initialize CPU feature data.
Packit 6c4009
   This file is part of the GNU C Library.
Packit 6c4009
   Copyright (C) 2008-2018 Free Software Foundation, Inc.
Packit 6c4009
Packit 6c4009
   The GNU C Library is free software; you can redistribute it and/or
Packit 6c4009
   modify it under the terms of the GNU Lesser General Public
Packit 6c4009
   License as published by the Free Software Foundation; either
Packit 6c4009
   version 2.1 of the License, or (at your option) any later version.
Packit 6c4009
Packit 6c4009
   The GNU C Library is distributed in the hope that it will be useful,
Packit 6c4009
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 6c4009
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 6c4009
   Lesser General Public License for more details.
Packit 6c4009
Packit 6c4009
   You should have received a copy of the GNU Lesser General Public
Packit 6c4009
   License along with the GNU C Library; if not, see
Packit 6c4009
   <http://www.gnu.org/licenses/>.  */
Packit 6c4009
Packit 6c4009
#include <cpuid.h>
Packit 6c4009
#include <dl-hwcap.h>
Packit 6c4009
#include <libc-pointer-arith.h>
Packit Service 4f62bc
#if IS_IN (libc) && !defined SHARED
Packit Service 4f62bc
# include <assert.h>
Packit Service 4f62bc
# include <unistd.h>
Packit Service 4f62bc
# include <dl-cacheinfo.h>
Packit Service 4f62bc
# include <cacheinfo.h>
Packit Service 4f62bc
#endif
Packit 6c4009
Packit 6c4009
#if HAVE_TUNABLES
Packit Service fc5bc2
# define TUNABLE_NAMESPACE cpu
Packit 6c4009
# include <unistd.h>		/* Get STDOUT_FILENO for _dl_printf.  */
Packit 6c4009
# include <elf/dl-tunables.h>
Packit 6c4009
Packit 6c4009
extern void TUNABLE_CALLBACK (set_hwcaps) (tunable_val_t *)
Packit 6c4009
  attribute_hidden;
Packit 6c4009
Packit 6c4009
# if CET_ENABLED
Packit 6c4009
extern void TUNABLE_CALLBACK (set_x86_ibt) (tunable_val_t *)
Packit 6c4009
  attribute_hidden;
Packit 6c4009
extern void TUNABLE_CALLBACK (set_x86_shstk) (tunable_val_t *)
Packit 6c4009
  attribute_hidden;
Packit 6c4009
# endif
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
#if CET_ENABLED
Packit 6c4009
# include <dl-cet.h>
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
static void
Packit Service a086f9
update_usable (struct cpu_features *cpu_features)
Packit 6c4009
{
Packit Service 352d1a
  /* Copy the cpuid bits to usable bits for CPU featuress whose usability
Packit Service 352d1a
     in user space can be detected without additonal OS support.  */
Packit Service 352d1a
  CPU_FEATURE_SET_USABLE (cpu_features, SSE3);
Packit Service 352d1a
  CPU_FEATURE_SET_USABLE (cpu_features, PCLMULQDQ);
Packit Service 352d1a
  CPU_FEATURE_SET_USABLE (cpu_features, SSSE3);
Packit Service 352d1a
  CPU_FEATURE_SET_USABLE (cpu_features, CMPXCHG16B);
Packit Service 352d1a
  CPU_FEATURE_SET_USABLE (cpu_features, SSE4_1);
Packit Service 352d1a
  CPU_FEATURE_SET_USABLE (cpu_features, SSE4_2);
Packit Service 352d1a
  CPU_FEATURE_SET_USABLE (cpu_features, MOVBE);
Packit Service 352d1a
  CPU_FEATURE_SET_USABLE (cpu_features, POPCNT);
Packit Service 352d1a
  CPU_FEATURE_SET_USABLE (cpu_features, AES);
Packit Service 352d1a
  CPU_FEATURE_SET_USABLE (cpu_features, OSXSAVE);
Packit Service 352d1a
  CPU_FEATURE_SET_USABLE (cpu_features, TSC);
Packit Service 352d1a
  CPU_FEATURE_SET_USABLE (cpu_features, CX8);
Packit Service 352d1a
  CPU_FEATURE_SET_USABLE (cpu_features, CMOV);
Packit Service 352d1a
  CPU_FEATURE_SET_USABLE (cpu_features, CLFSH);
Packit Service 352d1a
  CPU_FEATURE_SET_USABLE (cpu_features, MMX);
Packit Service 352d1a
  CPU_FEATURE_SET_USABLE (cpu_features, FXSR);
Packit Service 352d1a
  CPU_FEATURE_SET_USABLE (cpu_features, SSE);
Packit Service 352d1a
  CPU_FEATURE_SET_USABLE (cpu_features, SSE2);
Packit Service 352d1a
  CPU_FEATURE_SET_USABLE (cpu_features, HTT);
Packit Service 352d1a
  CPU_FEATURE_SET_USABLE (cpu_features, BMI1);
Packit Service 352d1a
  CPU_FEATURE_SET_USABLE (cpu_features, HLE);
Packit Service 352d1a
  CPU_FEATURE_SET_USABLE (cpu_features, BMI2);
Packit Service 352d1a
  CPU_FEATURE_SET_USABLE (cpu_features, ERMS);
Packit Service 352d1a
  CPU_FEATURE_SET_USABLE (cpu_features, RTM);
Packit Service 352d1a
  CPU_FEATURE_SET_USABLE (cpu_features, RDSEED);
Packit Service 352d1a
  CPU_FEATURE_SET_USABLE (cpu_features, ADX);
Packit Service 352d1a
  CPU_FEATURE_SET_USABLE (cpu_features, CLFLUSHOPT);
Packit Service 352d1a
  CPU_FEATURE_SET_USABLE (cpu_features, CLWB);
Packit Service 352d1a
  CPU_FEATURE_SET_USABLE (cpu_features, SHA);
Packit Service 352d1a
  CPU_FEATURE_SET_USABLE (cpu_features, PREFETCHWT1);
Packit Service 352d1a
  CPU_FEATURE_SET_USABLE (cpu_features, OSPKE);
Packit Service 352d1a
  CPU_FEATURE_SET_USABLE (cpu_features, WAITPKG);
Packit Service 352d1a
  CPU_FEATURE_SET_USABLE (cpu_features, GFNI);
Packit Service 352d1a
  CPU_FEATURE_SET_USABLE (cpu_features, RDPID);
Packit Service 352d1a
  CPU_FEATURE_SET_USABLE (cpu_features, CLDEMOTE);
Packit Service 352d1a
  CPU_FEATURE_SET_USABLE (cpu_features, MOVDIRI);
Packit Service 352d1a
  CPU_FEATURE_SET_USABLE (cpu_features, MOVDIR64B);
Packit Service 352d1a
  CPU_FEATURE_SET_USABLE (cpu_features, FSRM);
Packit Service 352d1a
  CPU_FEATURE_SET_USABLE (cpu_features, SERIALIZE);
Packit Service 352d1a
  CPU_FEATURE_SET_USABLE (cpu_features, TSXLDTRK);
Packit Service a086f9
  CPU_FEATURE_SET_USABLE (cpu_features, LAHF64_SAHF64);
Packit Service a086f9
  CPU_FEATURE_SET_USABLE (cpu_features, LZCNT);
Packit Service a086f9
  CPU_FEATURE_SET_USABLE (cpu_features, SSE4A);
Packit Service a086f9
  CPU_FEATURE_SET_USABLE (cpu_features, PREFETCHW);
Packit Service a086f9
  CPU_FEATURE_SET_USABLE (cpu_features, TBM);
Packit Service a086f9
  CPU_FEATURE_SET_USABLE (cpu_features, RDTSCP);
Packit Service a086f9
  CPU_FEATURE_SET_USABLE (cpu_features, WBNOINVD);
Packit Service 17b0f8
  CPU_FEATURE_SET_USABLE (cpu_features, FZLRM);
Packit Service 17b0f8
  CPU_FEATURE_SET_USABLE (cpu_features, FSRS);
Packit Service 17b0f8
  CPU_FEATURE_SET_USABLE (cpu_features, FSRCS);
Packit Service 881915
Packit 6c4009
  /* Can we call xgetbv?  */
Packit 6c4009
  if (CPU_FEATURES_CPU_P (cpu_features, OSXSAVE))
Packit 6c4009
    {
Packit 6c4009
      unsigned int xcrlow;
Packit 6c4009
      unsigned int xcrhigh;
Packit 6c4009
      asm ("xgetbv" : "=a" (xcrlow), "=d" (xcrhigh) : "c" (0));
Packit 6c4009
      /* Is YMM and XMM state usable?  */
Packit 6c4009
      if ((xcrlow & (bit_YMM_state | bit_XMM_state)) ==
Packit 6c4009
	  (bit_YMM_state | bit_XMM_state))
Packit 6c4009
	{
Packit 6c4009
	  /* Determine if AVX is usable.  */
Packit 6c4009
	  if (CPU_FEATURES_CPU_P (cpu_features, AVX))
Packit 6c4009
	    {
Packit Service a086f9
	      CPU_FEATURE_SET (cpu_features, AVX);
Packit 6c4009
	      /* The following features depend on AVX being usable.  */
Packit 6c4009
	      /* Determine if AVX2 is usable.  */
Packit 6c4009
	      if (CPU_FEATURES_CPU_P (cpu_features, AVX2))
Packit Service a086f9
		{
Packit Service a086f9
		  CPU_FEATURE_SET (cpu_features, AVX2);
Packit Service a086f9
Packit Service a086f9
		  /* Unaligned load with 256-bit AVX registers are faster
Packit Service a086f9
		     on Intel/AMD processors with AVX2.  */
Packit Service a086f9
		  cpu_features->preferred[index_arch_AVX_Fast_Unaligned_Load]
Packit Service a086f9
		    |= bit_arch_AVX_Fast_Unaligned_Load;
Packit Service a086f9
		}
Packit Service 0bc430
	      /* Determine if AVX-VNNI is usable.  */
Packit Service 0bc430
	      CPU_FEATURE_SET_USABLE (cpu_features, AVX_VNNI);
Packit 6c4009
	      /* Determine if FMA is usable.  */
Packit Service a086f9
	      CPU_FEATURE_SET_USABLE (cpu_features, FMA);
Packit Service 881915
	      /* Determine if VAES is usable.  */
Packit Service a086f9
	      CPU_FEATURE_SET_USABLE (cpu_features, VAES);
Packit Service 881915
	      /* Determine if VPCLMULQDQ is usable.  */
Packit Service a086f9
	      CPU_FEATURE_SET_USABLE (cpu_features, VPCLMULQDQ);
Packit Service 881915
	      /* Determine if XOP is usable.  */
Packit Service a086f9
	      CPU_FEATURE_SET_USABLE (cpu_features, XOP);
Packit Service 9ad5ef
	      /* Determine if F16C is usable.  */
Packit Service a086f9
	      CPU_FEATURE_SET_USABLE (cpu_features, F16C);
Packit 6c4009
	    }
Packit 6c4009
Packit 6c4009
	  /* Check if OPMASK state, upper 256-bit of ZMM0-ZMM15 and
Packit 6c4009
	     ZMM16-ZMM31 state are enabled.  */
Packit 6c4009
	  if ((xcrlow & (bit_Opmask_state | bit_ZMM0_15_state
Packit 6c4009
			 | bit_ZMM16_31_state)) ==
Packit 6c4009
	      (bit_Opmask_state | bit_ZMM0_15_state | bit_ZMM16_31_state))
Packit 6c4009
	    {
Packit 6c4009
	      /* Determine if AVX512F is usable.  */
Packit 6c4009
	      if (CPU_FEATURES_CPU_P (cpu_features, AVX512F))
Packit 6c4009
		{
Packit Service a086f9
		  CPU_FEATURE_SET (cpu_features, AVX512F);
Packit Service 881915
		  /* Determine if AVX512CD is usable.  */
Packit Service a086f9
		  CPU_FEATURE_SET_USABLE (cpu_features, AVX512CD);
Packit Service 881915
		  /* Determine if AVX512ER is usable.  */
Packit Service a086f9
		  CPU_FEATURE_SET_USABLE (cpu_features, AVX512ER);
Packit Service 881915
		  /* Determine if AVX512PF is usable.  */
Packit Service a086f9
		  CPU_FEATURE_SET_USABLE (cpu_features, AVX512PF);
Packit Service 881915
		  /* Determine if AVX512VL is usable.  */
Packit Service a086f9
		  CPU_FEATURE_SET_USABLE (cpu_features, AVX512VL);
Packit 6c4009
		  /* Determine if AVX512DQ is usable.  */
Packit Service a086f9
		  CPU_FEATURE_SET_USABLE (cpu_features, AVX512DQ);
Packit Service 881915
		  /* Determine if AVX512BW is usable.  */
Packit Service a086f9
		  CPU_FEATURE_SET_USABLE (cpu_features, AVX512BW);
Packit Service 881915
		  /* Determine if AVX512_4FMAPS is usable.  */
Packit Service a086f9
		  CPU_FEATURE_SET_USABLE (cpu_features, AVX512_4FMAPS);
Packit Service 881915
		  /* Determine if AVX512_4VNNIW is usable.  */
Packit Service a086f9
		  CPU_FEATURE_SET_USABLE (cpu_features, AVX512_4VNNIW);
Packit Service 881915
		  /* Determine if AVX512_BITALG is usable.  */
Packit Service a086f9
		  CPU_FEATURE_SET_USABLE (cpu_features, AVX512_BITALG);
Packit Service 881915
		  /* Determine if AVX512_IFMA is usable.  */
Packit Service a086f9
		  CPU_FEATURE_SET_USABLE (cpu_features, AVX512_IFMA);
Packit Service 881915
		  /* Determine if AVX512_VBMI is usable.  */
Packit Service a086f9
		  CPU_FEATURE_SET_USABLE (cpu_features, AVX512_VBMI);
Packit Service 881915
		  /* Determine if AVX512_VBMI2 is usable.  */
Packit Service a086f9
		  CPU_FEATURE_SET_USABLE (cpu_features, AVX512_VBMI2);
Packit Service 881915
		  /* Determine if is AVX512_VNNI usable.  */
Packit Service a086f9
		  CPU_FEATURE_SET_USABLE (cpu_features, AVX512_VNNI);
Packit Service 881915
		  /* Determine if AVX512_VPOPCNTDQ is usable.  */
Packit Service a086f9
		  CPU_FEATURE_SET_USABLE (cpu_features,
Packit Service a086f9
					  AVX512_VPOPCNTDQ);
Packit Service 262df3
		  /* Determine if AVX512_VP2INTERSECT is usable.  */
Packit Service a086f9
		  CPU_FEATURE_SET_USABLE (cpu_features,
Packit Service a086f9
					  AVX512_VP2INTERSECT);
Packit Service 262df3
		  /* Determine if AVX512_BF16 is usable.  */
Packit Service a086f9
		  CPU_FEATURE_SET_USABLE (cpu_features, AVX512_BF16);
Packit Service 93005a
		  /* Determine if AVX512_FP16 is usable.  */
Packit Service 93005a
		  CPU_FEATURE_SET_USABLE (cpu_features, AVX512_FP16);
Packit 6c4009
		}
Packit 6c4009
	    }
Packit 6c4009
	}
Packit 6c4009
Packit Service 0f79d0
      /* Are XTILECFG and XTILEDATA states usable?  */
Packit Service 0f79d0
      if ((xcrlow & (bit_XTILECFG_state | bit_XTILEDATA_state))
Packit Service 0f79d0
	  == (bit_XTILECFG_state | bit_XTILEDATA_state))
Packit Service 0f79d0
	{
Packit Service 0f79d0
	  /* Determine if AMX_BF16 is usable.  */
Packit Service a086f9
	  CPU_FEATURE_SET_USABLE (cpu_features, AMX_BF16);
Packit Service 0f79d0
	  /* Determine if AMX_TILE is usable.  */
Packit Service a086f9
	  CPU_FEATURE_SET_USABLE (cpu_features, AMX_TILE);
Packit Service 0f79d0
	  /* Determine if AMX_INT8 is usable.  */
Packit Service a086f9
	  CPU_FEATURE_SET_USABLE (cpu_features, AMX_INT8);
Packit Service 0f79d0
	}
Packit Service 0f79d0
Packit Service 352d1a
      /* These features are usable only when OSXSAVE is enabled.  */
Packit Service 352d1a
      CPU_FEATURE_SET (cpu_features, XSAVE);
Packit Service 352d1a
      CPU_FEATURE_SET_USABLE (cpu_features, XSAVEOPT);
Packit Service 352d1a
      CPU_FEATURE_SET_USABLE (cpu_features, XSAVEC);
Packit Service 352d1a
      CPU_FEATURE_SET_USABLE (cpu_features, XGETBV_ECX_1);
Packit Service a086f9
      CPU_FEATURE_SET_USABLE (cpu_features, XFD);
Packit Service a086f9
Packit 6c4009
      /* For _dl_runtime_resolve, set xsave_state_size to xsave area
Packit 6c4009
	 size + integer register save size and align it to 64 bytes.  */
Packit Service 881915
      if (cpu_features->basic.max_cpuid >= 0xd)
Packit 6c4009
	{
Packit 6c4009
	  unsigned int eax, ebx, ecx, edx;
Packit 6c4009
Packit 6c4009
	  __cpuid_count (0xd, 0, eax, ebx, ecx, edx);
Packit 6c4009
	  if (ebx != 0)
Packit 6c4009
	    {
Packit 6c4009
	      unsigned int xsave_state_full_size
Packit 6c4009
		= ALIGN_UP (ebx + STATE_SAVE_OFFSET, 64);
Packit 6c4009
Packit 6c4009
	      cpu_features->xsave_state_size
Packit 6c4009
		= xsave_state_full_size;
Packit 6c4009
	      cpu_features->xsave_state_full_size
Packit 6c4009
		= xsave_state_full_size;
Packit 6c4009
Packit 6c4009
	      /* Check if XSAVEC is available.  */
Packit Service 881915
	      if (CPU_FEATURES_CPU_P (cpu_features, XSAVEC))
Packit 6c4009
		{
Packit 6c4009
		  unsigned int xstate_comp_offsets[32];
Packit 6c4009
		  unsigned int xstate_comp_sizes[32];
Packit 6c4009
		  unsigned int i;
Packit 6c4009
Packit 6c4009
		  xstate_comp_offsets[0] = 0;
Packit 6c4009
		  xstate_comp_offsets[1] = 160;
Packit 6c4009
		  xstate_comp_offsets[2] = 576;
Packit 6c4009
		  xstate_comp_sizes[0] = 160;
Packit 6c4009
		  xstate_comp_sizes[1] = 256;
Packit 6c4009
Packit 6c4009
		  for (i = 2; i < 32; i++)
Packit 6c4009
		    {
Packit 6c4009
		      if ((STATE_SAVE_MASK & (1 << i)) != 0)
Packit 6c4009
			{
Packit 6c4009
			  __cpuid_count (0xd, i, eax, ebx, ecx, edx);
Packit 6c4009
			  xstate_comp_sizes[i] = eax;
Packit 6c4009
			}
Packit 6c4009
		      else
Packit 6c4009
			{
Packit 6c4009
			  ecx = 0;
Packit 6c4009
			  xstate_comp_sizes[i] = 0;
Packit 6c4009
			}
Packit 6c4009
Packit 6c4009
		      if (i > 2)
Packit 6c4009
			{
Packit 6c4009
			  xstate_comp_offsets[i]
Packit 6c4009
			    = (xstate_comp_offsets[i - 1]
Packit 6c4009
			       + xstate_comp_sizes[i -1]);
Packit 6c4009
			  if ((ecx & (1 << 1)) != 0)
Packit 6c4009
			    xstate_comp_offsets[i]
Packit 6c4009
			      = ALIGN_UP (xstate_comp_offsets[i], 64);
Packit 6c4009
			}
Packit 6c4009
		    }
Packit 6c4009
Packit 6c4009
		  /* Use XSAVEC.  */
Packit 6c4009
		  unsigned int size
Packit 6c4009
		    = xstate_comp_offsets[31] + xstate_comp_sizes[31];
Packit 6c4009
		  if (size)
Packit 6c4009
		    {
Packit 6c4009
		      cpu_features->xsave_state_size
Packit 6c4009
			= ALIGN_UP (size + STATE_SAVE_OFFSET, 64);
Packit Service a086f9
		      CPU_FEATURE_SET (cpu_features, XSAVEC);
Packit 6c4009
		    }
Packit 6c4009
		}
Packit 6c4009
	    }
Packit 6c4009
	}
Packit 6c4009
    }
Packit Service 262df3
Packit Service 262df3
  /* Determine if PKU is usable.  */
Packit Service 262df3
  if (CPU_FEATURES_CPU_P (cpu_features, OSPKE))
Packit Service a086f9
    CPU_FEATURE_SET (cpu_features, PKU);
Packit Service 6a3242
Packit Service 6a3242
  /* Determine if Key Locker instructions are usable.  */
Packit Service 6a3242
  if (CPU_FEATURES_CPU_P (cpu_features, AESKLE))
Packit Service 6a3242
    {
Packit Service 6a3242
      CPU_FEATURE_SET (cpu_features, AESKLE);
Packit Service 6a3242
      CPU_FEATURE_SET_USABLE (cpu_features, KL);
Packit Service 6a3242
      CPU_FEATURE_SET_USABLE (cpu_features, WIDE_KL);
Packit Service 6a3242
    }
Packit Service a086f9
}
Packit Service a086f9
Packit Service a086f9
static void
Packit Service a086f9
get_extended_indices (struct cpu_features *cpu_features)
Packit Service a086f9
{
Packit Service a086f9
  unsigned int eax, ebx, ecx, edx;
Packit Service a086f9
  __cpuid (0x80000000, eax, ebx, ecx, edx);
Packit Service a086f9
  if (eax >= 0x80000001)
Packit Service a086f9
    __cpuid (0x80000001,
Packit Service a086f9
	     cpu_features->features[COMMON_CPUID_INDEX_80000001].cpuid.eax,
Packit Service a086f9
	     cpu_features->features[COMMON_CPUID_INDEX_80000001].cpuid.ebx,
Packit Service a086f9
	     cpu_features->features[COMMON_CPUID_INDEX_80000001].cpuid.ecx,
Packit Service a086f9
	     cpu_features->features[COMMON_CPUID_INDEX_80000001].cpuid.edx);
Packit Service a086f9
  if (eax >= 0x80000007)
Packit Service a086f9
    __cpuid (0x80000007,
Packit Service a086f9
	     cpu_features->features[COMMON_CPUID_INDEX_80000007].cpuid.eax,
Packit Service a086f9
	     cpu_features->features[COMMON_CPUID_INDEX_80000007].cpuid.ebx,
Packit Service a086f9
	     cpu_features->features[COMMON_CPUID_INDEX_80000007].cpuid.ecx,
Packit Service a086f9
	     cpu_features->features[COMMON_CPUID_INDEX_80000007].cpuid.edx);
Packit Service a086f9
  if (eax >= 0x80000008)
Packit Service a086f9
    __cpuid (0x80000008,
Packit Service a086f9
	     cpu_features->features[COMMON_CPUID_INDEX_80000008].cpuid.eax,
Packit Service a086f9
	     cpu_features->features[COMMON_CPUID_INDEX_80000008].cpuid.ebx,
Packit Service a086f9
	     cpu_features->features[COMMON_CPUID_INDEX_80000008].cpuid.ecx,
Packit Service a086f9
	     cpu_features->features[COMMON_CPUID_INDEX_80000008].cpuid.edx);
Packit Service a086f9
}
Packit Service a086f9
Packit Service a086f9
static void
Packit Service a086f9
get_common_indices (struct cpu_features *cpu_features,
Packit Service a086f9
		    unsigned int *family, unsigned int *model,
Packit Service a086f9
		    unsigned int *extended_model, unsigned int *stepping)
Packit Service a086f9
{
Packit Service a086f9
  if (family)
Packit Service a086f9
    {
Packit Service a086f9
      unsigned int eax;
Packit Service a086f9
      __cpuid (1, eax,
Packit Service a086f9
	       cpu_features->features[COMMON_CPUID_INDEX_1].cpuid.ebx,
Packit Service a086f9
	       cpu_features->features[COMMON_CPUID_INDEX_1].cpuid.ecx,
Packit Service a086f9
	       cpu_features->features[COMMON_CPUID_INDEX_1].cpuid.edx);
Packit Service a086f9
      cpu_features->features[COMMON_CPUID_INDEX_1].cpuid.eax = eax;
Packit Service a086f9
      *family = (eax >> 8) & 0x0f;
Packit Service a086f9
      *model = (eax >> 4) & 0x0f;
Packit Service a086f9
      *extended_model = (eax >> 12) & 0xf0;
Packit Service a086f9
      *stepping = eax & 0x0f;
Packit Service a086f9
      if (*family == 0x0f)
Packit Service a086f9
	{
Packit Service a086f9
	  *family += (eax >> 20) & 0xff;
Packit Service a086f9
	  *model += *extended_model;
Packit Service a086f9
	}
Packit Service a086f9
    }
Packit Service a086f9
Packit Service a086f9
  if (cpu_features->basic.max_cpuid >= 7)
Packit Service a086f9
    {
Packit Service a086f9
      __cpuid_count (7, 0,
Packit Service a086f9
		     cpu_features->features[COMMON_CPUID_INDEX_7].cpuid.eax,
Packit Service a086f9
		     cpu_features->features[COMMON_CPUID_INDEX_7].cpuid.ebx,
Packit Service a086f9
		     cpu_features->features[COMMON_CPUID_INDEX_7].cpuid.ecx,
Packit Service a086f9
		     cpu_features->features[COMMON_CPUID_INDEX_7].cpuid.edx);
Packit Service a086f9
      __cpuid_count (7, 1,
Packit Service a086f9
		     cpu_features->features[COMMON_CPUID_INDEX_7_ECX_1].cpuid.eax,
Packit Service a086f9
		     cpu_features->features[COMMON_CPUID_INDEX_7_ECX_1].cpuid.ebx,
Packit Service a086f9
		     cpu_features->features[COMMON_CPUID_INDEX_7_ECX_1].cpuid.ecx,
Packit Service a086f9
		     cpu_features->features[COMMON_CPUID_INDEX_7_ECX_1].cpuid.edx);
Packit Service a086f9
    }
Packit Service a086f9
Packit Service a086f9
  if (cpu_features->basic.max_cpuid >= 0xd)
Packit Service a086f9
    __cpuid_count (0xd, 1,
Packit Service a086f9
		   cpu_features->features[COMMON_CPUID_INDEX_D_ECX_1].cpuid.eax,
Packit Service a086f9
		   cpu_features->features[COMMON_CPUID_INDEX_D_ECX_1].cpuid.ebx,
Packit Service a086f9
		   cpu_features->features[COMMON_CPUID_INDEX_D_ECX_1].cpuid.ecx,
Packit Service a086f9
		   cpu_features->features[COMMON_CPUID_INDEX_D_ECX_1].cpuid.edx);
Packit Service a086f9
Packit Service 6a3242
  if (cpu_features->basic.max_cpuid >= 0x19)
Packit Service 6a3242
    __cpuid_count (0x19, 0,
Packit Service 6a3242
		   cpu_features->features[COMMON_CPUID_INDEX_19].cpuid.eax,
Packit Service 6a3242
		   cpu_features->features[COMMON_CPUID_INDEX_19].cpuid.ebx,
Packit Service 6a3242
		   cpu_features->features[COMMON_CPUID_INDEX_19].cpuid.ecx,
Packit Service 6a3242
		   cpu_features->features[COMMON_CPUID_INDEX_19].cpuid.edx);
Packit Service da784a
}
Packit Service da784a
Packit Service 881915
_Static_assert (((index_arch_Fast_Unaligned_Load
Packit Service 881915
		  == index_arch_Fast_Unaligned_Copy)
Packit Service 881915
		 && (index_arch_Fast_Unaligned_Load
Packit Service 881915
		     == index_arch_Prefer_PMINUB_for_stringop)
Packit Service 881915
		 && (index_arch_Fast_Unaligned_Load
Packit Service 881915
		     == index_arch_Slow_SSE4_2)
Packit Service 881915
		 && (index_arch_Fast_Unaligned_Load
Packit Service 881915
		     == index_arch_Fast_Rep_String)
Packit Service 881915
		 && (index_arch_Fast_Unaligned_Load
Packit Service 881915
		     == index_arch_Fast_Copy_Backward)),
Packit Service 881915
		"Incorrect index_arch_Fast_Unaligned_Load");
Packit Service 881915
Packit 6c4009
static inline void
Packit 6c4009
init_cpu_features (struct cpu_features *cpu_features)
Packit 6c4009
{
Packit 6c4009
  unsigned int ebx, ecx, edx;
Packit 6c4009
  unsigned int family = 0;
Packit 6c4009
  unsigned int model = 0;
Packit Service 881915
  unsigned int stepping = 0;
Packit 6c4009
  enum cpu_features_kind kind;
Packit 6c4009
Packit 6c4009
#if !HAS_CPUID
Packit 6c4009
  if (__get_cpuid_max (0, 0) == 0)
Packit 6c4009
    {
Packit 6c4009
      kind = arch_kind_other;
Packit 6c4009
      goto no_cpuid;
Packit 6c4009
    }
Packit 6c4009
#endif
Packit 6c4009
Packit Service 881915
  __cpuid (0, cpu_features->basic.max_cpuid, ebx, ecx, edx);
Packit 6c4009
Packit 6c4009
  /* This spells out "GenuineIntel".  */
Packit 6c4009
  if (ebx == 0x756e6547 && ecx == 0x6c65746e && edx == 0x49656e69)
Packit 6c4009
    {
Packit Service 881915
      unsigned int extended_model;
Packit 6c4009
Packit 6c4009
      kind = arch_kind_intel;
Packit 6c4009
Packit Service 7be6e8
      get_common_indices (cpu_features, &family, &model, &extended_model,
Packit 6c4009
			  &stepping);
Packit 6c4009
Packit 6c4009
      get_extended_indices (cpu_features);
Packit 6c4009
Packit Service a086f9
      update_usable (cpu_features);
Packit Service a086f9
Packit 6c4009
      if (family == 0x06)
Packit 6c4009
	{
Packit 6c4009
	  model += extended_model;
Packit 6c4009
	  switch (model)
Packit 6c4009
	    {
Packit 6c4009
	    case 0x1c:
Packit 6c4009
	    case 0x26:
Packit 6c4009
	      /* BSF is slow on Atom.  */
Packit Service 262df3
	      cpu_features->preferred[index_arch_Slow_BSF]
Packit 6c4009
		|= bit_arch_Slow_BSF;
Packit 6c4009
	      break;
Packit 6c4009
Packit 6c4009
	    case 0x57:
Packit 6c4009
	      /* Knights Landing.  Enable Silvermont optimizations.  */
Packit 6c4009
Packit Service d8075b
	    case 0x7a:
Packit Service d8075b
	      /* Unaligned load versions are faster than SSSE3
Packit Service d8075b
		 on Goldmont Plus.  */
Packit Service d8075b
Packit 6c4009
	    case 0x5c:
Packit 6c4009
	    case 0x5f:
Packit 6c4009
	      /* Unaligned load versions are faster than SSSE3
Packit 6c4009
		 on Goldmont.  */
Packit 6c4009
Packit 6c4009
	    case 0x4c:
Packit Service d8075b
	    case 0x5a:
Packit Service d8075b
	    case 0x75:
Packit 6c4009
	      /* Airmont is a die shrink of Silvermont.  */
Packit 6c4009
Packit 6c4009
	    case 0x37:
Packit 6c4009
	    case 0x4a:
Packit 6c4009
	    case 0x4d:
Packit 6c4009
	    case 0x5d:
Packit 6c4009
	      /* Unaligned load versions are faster than SSSE3
Packit 6c4009
		 on Silvermont.  */
Packit Service 262df3
	      cpu_features->preferred[index_arch_Fast_Unaligned_Load]
Packit 6c4009
		|= (bit_arch_Fast_Unaligned_Load
Packit 6c4009
		    | bit_arch_Fast_Unaligned_Copy
Packit 6c4009
		    | bit_arch_Prefer_PMINUB_for_stringop
Packit 6c4009
		    | bit_arch_Slow_SSE4_2);
Packit 6c4009
	      break;
Packit 6c4009
Packit Service d8075b
	    case 0x86:
Packit Service d8075b
	    case 0x96:
Packit Service d8075b
	    case 0x9c:
Packit Service d8075b
	      /* Enable rep string instructions, unaligned load, unaligned
Packit Service d8075b
	         copy, pminub and avoid SSE 4.2 on Tremont.  */
Packit Service 262df3
	      cpu_features->preferred[index_arch_Fast_Rep_String]
Packit Service d8075b
		|= (bit_arch_Fast_Rep_String
Packit Service d8075b
		    | bit_arch_Fast_Unaligned_Load
Packit Service d8075b
		    | bit_arch_Fast_Unaligned_Copy
Packit Service d8075b
		    | bit_arch_Prefer_PMINUB_for_stringop
Packit Service d8075b
		    | bit_arch_Slow_SSE4_2);
Packit Service d8075b
	      break;
Packit Service d8075b
Packit 6c4009
	    default:
Packit 6c4009
	      /* Unknown family 0x06 processors.  Assuming this is one
Packit 6c4009
		 of Core i3/i5/i7 processors if AVX is available.  */
Packit 6c4009
	      if (!CPU_FEATURES_CPU_P (cpu_features, AVX))
Packit 6c4009
		break;
Packit Service 81063c
	      /* Fall through.  */
Packit 6c4009
Packit 6c4009
	    case 0x1a:
Packit 6c4009
	    case 0x1e:
Packit 6c4009
	    case 0x1f:
Packit 6c4009
	    case 0x25:
Packit 6c4009
	    case 0x2c:
Packit 6c4009
	    case 0x2e:
Packit 6c4009
	    case 0x2f:
Packit 6c4009
	      /* Rep string instructions, unaligned load, unaligned copy,
Packit 6c4009
		 and pminub are fast on Intel Core i3, i5 and i7.  */
Packit Service 262df3
	      cpu_features->preferred[index_arch_Fast_Rep_String]
Packit 6c4009
		|= (bit_arch_Fast_Rep_String
Packit 6c4009
		    | bit_arch_Fast_Unaligned_Load
Packit 6c4009
		    | bit_arch_Fast_Unaligned_Copy
Packit 6c4009
		    | bit_arch_Prefer_PMINUB_for_stringop);
Packit 6c4009
	      break;
Packit Service 831369
	    }
Packit 6c4009
Packit Service 831369
	 /* Disable TSX on some Haswell processors to avoid TSX on kernels that
Packit Service 831369
	    weren't updated with the latest microcode package (which disables
Packit Service 831369
	    broken feature by default).  */
Packit Service 831369
	 switch (model)
Packit Service 831369
	    {
Packit 6c4009
	    case 0x3f:
Packit 6c4009
	      /* Xeon E7 v3 with stepping >= 4 has working TSX.  */
Packit 6c4009
	      if (stepping >= 4)
Packit 6c4009
		break;
Packit Service 81063c
	      /* Fall through.  */
Packit 6c4009
	    case 0x3c:
Packit 6c4009
	    case 0x45:
Packit 6c4009
	    case 0x46:
Packit 6c4009
	      /* Disable Intel TSX on Haswell processors (except Xeon E7 v3
Packit 6c4009
		 with stepping >= 4) to avoid TSX on kernels that weren't
Packit 6c4009
		 updated with the latest microcode package (which disables
Packit 6c4009
		 broken feature by default).  */
Packit Service a086f9
	      CPU_FEATURE_UNSET (cpu_features, RTM);
Packit 6c4009
	      break;
Packit 6c4009
	    }
Packit 6c4009
	}
Packit 6c4009
Packit 6c4009
Packit 6c4009
      /* Since AVX512ER is unique to Xeon Phi, set Prefer_No_VZEROUPPER
Packit 6c4009
         if AVX512ER is available.  Don't use AVX512 to avoid lower CPU
Packit 6c4009
	 frequency if AVX512ER isn't available.  */
Packit 6c4009
      if (CPU_FEATURES_CPU_P (cpu_features, AVX512ER))
Packit Service 262df3
	cpu_features->preferred[index_arch_Prefer_No_VZEROUPPER]
Packit 6c4009
	  |= bit_arch_Prefer_No_VZEROUPPER;
Packit 6c4009
      else
Packit Service 262df3
	cpu_features->preferred[index_arch_Prefer_No_AVX512]
Packit 6c4009
	  |= bit_arch_Prefer_No_AVX512;
Packit 6c4009
    }
Packit 6c4009
  /* This spells out "AuthenticAMD".  */
Packit 6c4009
  else if (ebx == 0x68747541 && ecx == 0x444d4163 && edx == 0x69746e65)
Packit 6c4009
    {
Packit Service 881915
      unsigned int extended_model;
Packit 6c4009
Packit 6c4009
      kind = arch_kind_amd;
Packit 6c4009
Packit Service 7be6e8
      get_common_indices (cpu_features, &family, &model, &extended_model,
Packit 6c4009
			  &stepping);
Packit 6c4009
Packit 6c4009
      get_extended_indices (cpu_features);
Packit 6c4009
Packit Service a086f9
      update_usable (cpu_features);
Packit 6c4009
Packit Service a086f9
      ecx = cpu_features->features[COMMON_CPUID_INDEX_1].cpuid.ecx;
Packit Service a086f9
Packit Service a086f9
      if (CPU_FEATURE_USABLE_P (cpu_features, AVX))
Packit 6c4009
	{
Packit 6c4009
	  /* Since the FMA4 bit is in COMMON_CPUID_INDEX_80000001 and
Packit 6c4009
	     FMA4 requires AVX, determine if FMA4 is usable here.  */
Packit Service a086f9
	  CPU_FEATURE_SET_USABLE (cpu_features, FMA4);
Packit 6c4009
	}
Packit 6c4009
Packit 6c4009
      if (family == 0x15)
Packit 6c4009
	{
Packit 6c4009
	  /* "Excavator"   */
Packit 6c4009
	  if (model >= 0x60 && model <= 0x7f)
Packit 6c4009
	  {
Packit Service 262df3
	    cpu_features->preferred[index_arch_Fast_Unaligned_Load]
Packit 6c4009
	      |= (bit_arch_Fast_Unaligned_Load
Packit 6c4009
		  | bit_arch_Fast_Copy_Backward);
Packit 6c4009
Packit 6c4009
	    /* Unaligned AVX loads are slower.*/
Packit Service 262df3
	    cpu_features->preferred[index_arch_AVX_Fast_Unaligned_Load]
Packit Service 262df3
	      &= ~bit_arch_AVX_Fast_Unaligned_Load;
Packit 6c4009
	  }
Packit 6c4009
	}
Packit 6c4009
    }
Packit Service d59736
  /* This spells out "CentaurHauls" or " Shanghai ".  */
Packit Service d59736
  else if ((ebx == 0x746e6543 && ecx == 0x736c7561 && edx == 0x48727561)
Packit Service d59736
	   || (ebx == 0x68532020 && ecx == 0x20206961 && edx == 0x68676e61))
Packit Service d59736
    {
Packit Service d59736
      unsigned int extended_model, stepping;
Packit Service d59736
Packit Service d59736
      kind = arch_kind_zhaoxin;
Packit Service d59736
Packit Service d59736
      get_common_indices (cpu_features, &family, &model, &extended_model,
Packit Service d59736
			  &stepping);
Packit Service d59736
Packit Service d59736
      get_extended_indices (cpu_features);
Packit Service d59736
Packit Service a086f9
      update_usable (cpu_features);
Packit Service a086f9
Packit Service d59736
      model += extended_model;
Packit Service d59736
      if (family == 0x6)
Packit Service d59736
        {
Packit Service d59736
          if (model == 0xf || model == 0x19)
Packit Service d59736
            {
Packit Service a086f9
	      CPU_FEATURE_UNSET (cpu_features, AVX);
Packit Service a086f9
	      CPU_FEATURE_UNSET (cpu_features, AVX2);
Packit Service d59736
Packit Service 262df3
              cpu_features->preferred[index_arch_Slow_SSE4_2]
Packit Service 262df3
                |= bit_arch_Slow_SSE4_2;
Packit Service d59736
Packit Service 262df3
	      cpu_features->preferred[index_arch_AVX_Fast_Unaligned_Load]
Packit Service 262df3
		&= ~bit_arch_AVX_Fast_Unaligned_Load;
Packit Service d59736
            }
Packit Service d59736
        }
Packit Service d59736
      else if (family == 0x7)
Packit Service d59736
        {
Packit Service 262df3
	  if (model == 0x1b)
Packit Service 262df3
	    {
Packit Service a086f9
	      CPU_FEATURE_UNSET (cpu_features, AVX);
Packit Service a086f9
	      CPU_FEATURE_UNSET (cpu_features, AVX2);
Packit Service d59736
Packit Service 262df3
	      cpu_features->preferred[index_arch_Slow_SSE4_2]
Packit Service 262df3
		|= bit_arch_Slow_SSE4_2;
Packit Service 262df3
Packit Service 262df3
	      cpu_features->preferred[index_arch_AVX_Fast_Unaligned_Load]
Packit Service 262df3
		&= ~bit_arch_AVX_Fast_Unaligned_Load;
Packit Service 262df3
	    }
Packit Service 262df3
	  else if (model == 0x3b)
Packit Service 262df3
	    {
Packit Service a086f9
	      CPU_FEATURE_UNSET (cpu_features, AVX);
Packit Service a086f9
	      CPU_FEATURE_UNSET (cpu_features, AVX2);
Packit Service d59736
Packit Service 262df3
	      cpu_features->preferred[index_arch_AVX_Fast_Unaligned_Load]
Packit Service 262df3
		&= ~bit_arch_AVX_Fast_Unaligned_Load;
Packit Service 262df3
	    }
Packit Service 262df3
	}
Packit Service d59736
    }
Packit 6c4009
  else
Packit 6c4009
    {
Packit 6c4009
      kind = arch_kind_other;
Packit Service 7be6e8
      get_common_indices (cpu_features, NULL, NULL, NULL, NULL);
Packit Service a086f9
      update_usable (cpu_features);
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  /* Support i586 if CX8 is available.  */
Packit 6c4009
  if (CPU_FEATURES_CPU_P (cpu_features, CX8))
Packit Service 262df3
    cpu_features->preferred[index_arch_I586] |= bit_arch_I586;
Packit 6c4009
Packit 6c4009
  /* Support i686 if CMOV is available.  */
Packit 6c4009
  if (CPU_FEATURES_CPU_P (cpu_features, CMOV))
Packit Service 262df3
    cpu_features->preferred[index_arch_I686] |= bit_arch_I686;
Packit 6c4009
Packit 6c4009
#if !HAS_CPUID
Packit 6c4009
no_cpuid:
Packit 6c4009
#endif
Packit 6c4009
Packit Service 881915
  cpu_features->basic.kind = kind;
Packit Service 881915
  cpu_features->basic.family = family;
Packit Service 881915
  cpu_features->basic.model = model;
Packit Service 881915
  cpu_features->basic.stepping = stepping;
Packit 6c4009
Packit 6c4009
#if HAVE_TUNABLES
Packit 6c4009
  TUNABLE_GET (hwcaps, tunable_val_t *, TUNABLE_CALLBACK (set_hwcaps));
Packit 6c4009
  cpu_features->non_temporal_threshold
Packit 6c4009
    = TUNABLE_GET (x86_non_temporal_threshold, long int, NULL);
Packit Service bed2b7
  cpu_features->rep_movsb_threshold
Packit Service bed2b7
    = TUNABLE_GET (x86_rep_movsb_threshold, long int, NULL);
Packit Service bed2b7
  cpu_features->rep_stosb_threshold
Packit Service bed2b7
    = TUNABLE_GET (x86_rep_stosb_threshold, long int, NULL);
Packit 6c4009
  cpu_features->data_cache_size
Packit 6c4009
    = TUNABLE_GET (x86_data_cache_size, long int, NULL);
Packit 6c4009
  cpu_features->shared_cache_size
Packit 6c4009
    = TUNABLE_GET (x86_shared_cache_size, long int, NULL);
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
  /* Reuse dl_platform, dl_hwcap and dl_hwcap_mask for x86.  */
Packit 6c4009
#if !HAVE_TUNABLES && defined SHARED
Packit Service fc5bc2
  /* The glibc.cpu.hwcap_mask tunable is initialized already, so no need to do
Packit 6c4009
     this.  */
Packit 6c4009
  GLRO(dl_hwcap_mask) = HWCAP_IMPORTANT;
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
#ifdef __x86_64__
Packit 6c4009
  GLRO(dl_hwcap) = HWCAP_X86_64;
Packit Service 881915
  if (cpu_features->basic.kind == arch_kind_intel)
Packit 6c4009
    {
Packit 6c4009
      const char *platform = NULL;
Packit 6c4009
Packit Service a086f9
      if (CPU_FEATURE_USABLE_P (cpu_features, AVX512CD))
Packit 6c4009
	{
Packit Service a086f9
	  if (CPU_FEATURE_USABLE_P (cpu_features, AVX512ER))
Packit 6c4009
	    {
Packit Service a086f9
	      if (CPU_FEATURE_USABLE_P (cpu_features, AVX512PF))
Packit 6c4009
		platform = "xeon_phi";
Packit 6c4009
	    }
Packit 6c4009
	  else
Packit 6c4009
	    {
Packit Service a086f9
	      if (CPU_FEATURE_USABLE_P (cpu_features, AVX512BW)
Packit Service a086f9
		  && CPU_FEATURE_USABLE_P (cpu_features, AVX512DQ)
Packit Service a086f9
		  && CPU_FEATURE_USABLE_P (cpu_features, AVX512VL))
Packit 6c4009
		GLRO(dl_hwcap) |= HWCAP_X86_AVX512_1;
Packit 6c4009
	    }
Packit 6c4009
	}
Packit 6c4009
Packit 6c4009
      if (platform == NULL
Packit Service a086f9
	  && CPU_FEATURE_USABLE_P (cpu_features, AVX2)
Packit Service a086f9
	  && CPU_FEATURE_USABLE_P (cpu_features, FMA)
Packit Service a086f9
	  && CPU_FEATURE_USABLE_P (cpu_features, BMI1)
Packit Service a086f9
	  && CPU_FEATURE_USABLE_P (cpu_features, BMI2)
Packit Service a086f9
	  && CPU_FEATURE_USABLE_P (cpu_features, LZCNT)
Packit Service a086f9
	  && CPU_FEATURE_USABLE_P (cpu_features, MOVBE)
Packit Service a086f9
	  && CPU_FEATURE_USABLE_P (cpu_features, POPCNT))
Packit 6c4009
	platform = "haswell";
Packit 6c4009
Packit 6c4009
      if (platform != NULL)
Packit 6c4009
	GLRO(dl_platform) = platform;
Packit 6c4009
    }
Packit 6c4009
#else
Packit 6c4009
  GLRO(dl_hwcap) = 0;
Packit Service a086f9
  if (CPU_FEATURE_USABLE_P (cpu_features, SSE2))
Packit 6c4009
    GLRO(dl_hwcap) |= HWCAP_X86_SSE2;
Packit 6c4009
Packit 6c4009
  if (CPU_FEATURES_ARCH_P (cpu_features, I686))
Packit 6c4009
    GLRO(dl_platform) = "i686";
Packit 6c4009
  else if (CPU_FEATURES_ARCH_P (cpu_features, I586))
Packit 6c4009
    GLRO(dl_platform) = "i586";
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
#if CET_ENABLED
Packit 6c4009
# if HAVE_TUNABLES
Packit 6c4009
  TUNABLE_GET (x86_ibt, tunable_val_t *,
Packit 6c4009
	       TUNABLE_CALLBACK (set_x86_ibt));
Packit 6c4009
  TUNABLE_GET (x86_shstk, tunable_val_t *,
Packit 6c4009
	       TUNABLE_CALLBACK (set_x86_shstk));
Packit 6c4009
# endif
Packit 6c4009
Packit 6c4009
  /* Check CET status.  */
Packit 6c4009
  unsigned int cet_status = get_cet_status ();
Packit 6c4009
Packit 6c4009
  if (cet_status)
Packit 6c4009
    {
Packit Service 78f55d
      GL(dl_x86_feature_1) = cet_status;
Packit 6c4009
Packit 6c4009
# ifndef SHARED
Packit 6c4009
      /* Check if IBT and SHSTK are enabled by kernel.  */
Packit 6c4009
      if ((cet_status & GNU_PROPERTY_X86_FEATURE_1_IBT)
Packit 6c4009
	  || (cet_status & GNU_PROPERTY_X86_FEATURE_1_SHSTK))
Packit 6c4009
	{
Packit 6c4009
	  /* Disable IBT and/or SHSTK if they are enabled by kernel, but
Packit 6c4009
	     disabled by environment variable:
Packit 6c4009
Packit Service fc5bc2
	     GLIBC_TUNABLES=glibc.cpu.hwcaps=-IBT,-SHSTK
Packit 6c4009
	   */
Packit 6c4009
	  unsigned int cet_feature = 0;
Packit Service a0b098
	  if (!HAS_CPU_FEATURE (IBT))
Packit 6c4009
	    cet_feature |= GNU_PROPERTY_X86_FEATURE_1_IBT;
Packit Service a0b098
	  if (!HAS_CPU_FEATURE (SHSTK))
Packit 6c4009
	    cet_feature |= GNU_PROPERTY_X86_FEATURE_1_SHSTK;
Packit 6c4009
Packit 6c4009
	  if (cet_feature)
Packit 6c4009
	    {
Packit 6c4009
	      int res = dl_cet_disable_cet (cet_feature);
Packit 6c4009
Packit 6c4009
	      /* Clear the disabled bits in dl_x86_feature_1.  */
Packit 6c4009
	      if (res == 0)
Packit Service 78f55d
		GL(dl_x86_feature_1) &= ~cet_feature;
Packit 6c4009
	    }
Packit 6c4009
Packit 6c4009
	  /* Lock CET if IBT or SHSTK is enabled in executable.  Don't
Packit Service 78f55d
	     lock CET if IBT or SHSTK is enabled permissively.  */
Packit Service 78f55d
	  if (GL(dl_x86_feature_control).ibt != cet_permissive
Packit Service 78f55d
	      && GL(dl_x86_feature_control).shstk != cet_permissive)
Packit 6c4009
	    dl_cet_lock_cet ();
Packit 6c4009
	}
Packit 6c4009
# endif
Packit 6c4009
    }
Packit 6c4009
#endif
Packit Service 4f62bc
Packit Service 4f62bc
#ifndef SHARED
Packit Service 4f62bc
  /* NB: In libc.a, call init_cacheinfo.  */
Packit Service 4f62bc
  init_cacheinfo ();
Packit Service 4f62bc
#endif
Packit 6c4009
}