tunables: Use glibc.tune.hwcap_mask tunable instead of _dl_hwcap_mask

Drop _dl_hwcap_mask when building with tunables.  This completes the
transition of hwcap_mask reading from _dl_hwcap_mask to tunables.

	* elf/dl-hwcaps.h: New file.
	* elf/dl-hwcaps.c: Include it.
	(_dl_important_hwcaps)[HAVE_TUNABLES]: Read and update
	glibc.tune.hwcap_mask.
	* elf/dl-cache.c: Include dl-hwcaps.h.
	(_dl_load_cache_lookup)[HAVE_TUNABLES]: Read
	glibc.tune.hwcap_mask.
	* sysdeps/sparc/sparc32/dl-machine.h: Likewise.
	* elf/dl-support.c (_dl_hwcap2)[HAVE_TUNABLES]: Drop
	_dl_hwcap_mask.
	* elf/rtld.c (rtld_global_ro)[HAVE_TUNABLES]: Drop
	_dl_hwcap_mask.
	(process_envvars)[HAVE_TUNABLES]: Likewise.
	* sysdeps/generic/ldsodefs.h (rtld_global_ro)[HAVE_TUNABLES]:
	Likewise.
	* sysdeps/x86/cpu-features.c (init_cpu_features): Don't
	initialize dl_hwcap_mask when tunables are enabled.
This commit is contained in:
Siddhesh Poyarekar 2017-06-01 22:32:03 +05:30
parent 6482e63403
commit ff08fc59e3
9 changed files with 77 additions and 4 deletions

View File

@ -1,5 +1,23 @@
2017-06-07 Siddhesh Poyarekar <siddhesh@sourceware.org> 2017-06-07 Siddhesh Poyarekar <siddhesh@sourceware.org>
* elf/dl-hwcaps.h: New file.
* elf/dl-hwcaps.c: Include it.
(_dl_important_hwcaps)[HAVE_TUNABLES]: Read and update
glibc.tune.hwcap_mask.
* elf/dl-cache.c: Include dl-hwcaps.h.
(_dl_load_cache_lookup)[HAVE_TUNABLES]: Read
glibc.tune.hwcap_mask.
* sysdeps/sparc/sparc32/dl-machine.h: Likewise.
* elf/dl-support.c (_dl_hwcap2)[HAVE_TUNABLES]: Drop
_dl_hwcap_mask.
* elf/rtld.c (rtld_global_ro)[HAVE_TUNABLES]: Drop
_dl_hwcap_mask.
(process_envvars)[HAVE_TUNABLES]: Likewise.
* sysdeps/generic/ldsodefs.h (rtld_global_ro)[HAVE_TUNABLES]:
Likewise.
* sysdeps/x86/cpu-features.c (init_cpu_features): Don't
initialize dl_hwcap_mask when tunables are enabled.
* sysdeps/unix/sysv/linux/i386/dl-procinfo.h: Add include * sysdeps/unix/sysv/linux/i386/dl-procinfo.h: Add include
guard. guard.
* sysdeps/unix/sysv/linux/s390/dl-procinfo.h: Likewise. * sysdeps/unix/sysv/linux/s390/dl-procinfo.h: Likewise.

View File

@ -24,6 +24,7 @@
#include <dl-procinfo.h> #include <dl-procinfo.h>
#include <stdint.h> #include <stdint.h>
#include <_itoa.h> #include <_itoa.h>
#include <dl-hwcaps.h>
#ifndef _DL_PLATFORMS_COUNT #ifndef _DL_PLATFORMS_COUNT
# define _DL_PLATFORMS_COUNT 0 # define _DL_PLATFORMS_COUNT 0
@ -258,8 +259,10 @@ _dl_load_cache_lookup (const char *name)
if (platform != (uint64_t) -1) if (platform != (uint64_t) -1)
platform = 1ULL << platform; platform = 1ULL << platform;
uint64_t hwcap_mask = GET_HWCAP_MASK();
#define _DL_HWCAP_TLS_MASK (1LL << 63) #define _DL_HWCAP_TLS_MASK (1LL << 63)
uint64_t hwcap_exclude = ~((GLRO(dl_hwcap) & GLRO(dl_hwcap_mask)) uint64_t hwcap_exclude = ~((GLRO(dl_hwcap) & hwcap_mask)
| _DL_HWCAP_PLATFORM | _DL_HWCAP_TLS_MASK); | _DL_HWCAP_PLATFORM | _DL_HWCAP_TLS_MASK);
/* Only accept hwcap if it's for the right platform. */ /* Only accept hwcap if it's for the right platform. */

View File

@ -24,6 +24,7 @@
#include <ldsodefs.h> #include <ldsodefs.h>
#include <dl-procinfo.h> #include <dl-procinfo.h>
#include <dl-hwcaps.h>
#ifdef _DL_FIRST_PLATFORM #ifdef _DL_FIRST_PLATFORM
# define _DL_FIRST_EXTRA (_DL_FIRST_PLATFORM + _DL_PLATFORMS_COUNT) # define _DL_FIRST_EXTRA (_DL_FIRST_PLATFORM + _DL_PLATFORMS_COUNT)
@ -37,8 +38,9 @@ internal_function
_dl_important_hwcaps (const char *platform, size_t platform_len, size_t *sz, _dl_important_hwcaps (const char *platform, size_t platform_len, size_t *sz,
size_t *max_capstrlen) size_t *max_capstrlen)
{ {
uint64_t hwcap_mask = GET_HWCAP_MASK();
/* Determine how many important bits are set. */ /* Determine how many important bits are set. */
uint64_t masked = GLRO(dl_hwcap) & GLRO(dl_hwcap_mask); uint64_t masked = GLRO(dl_hwcap) & hwcap_mask;
size_t cnt = platform != NULL; size_t cnt = platform != NULL;
size_t n, m; size_t n, m;
size_t total; size_t total;
@ -125,7 +127,12 @@ _dl_important_hwcaps (const char *platform, size_t platform_len, size_t *sz,
LD_HWCAP_MASK environment variable (or default HWCAP_IMPORTANT). LD_HWCAP_MASK environment variable (or default HWCAP_IMPORTANT).
So there is no way to request ignoring an OS-supplied dsocap So there is no way to request ignoring an OS-supplied dsocap
string and bit like you can ignore an OS-supplied HWCAP bit. */ string and bit like you can ignore an OS-supplied HWCAP bit. */
GLRO(dl_hwcap_mask) |= (uint64_t) mask << _DL_FIRST_EXTRA; hwcap_mask |= (uint64_t) mask << _DL_FIRST_EXTRA;
#if HAVE_TUNABLES
TUNABLE_SET (glibc, tune, hwcap_mask, uint64_t, hwcap_mask);
#else
GLRO(dl_hwcap_mask) = hwcap_mask;
#endif
size_t len; size_t len;
for (const char *p = dsocaps; p < dsocaps + dsocapslen; p += len + 1) for (const char *p = dsocaps; p < dsocaps + dsocapslen; p += len + 1)
{ {

31
elf/dl-hwcaps.h Normal file
View File

@ -0,0 +1,31 @@
/* Hardware capability support for run-time dynamic loader.
Copyright (C) 2017 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
<http://www.gnu.org/licenses/>. */
#include <elf/dl-tunables.h>
#ifdef SHARED
# if HAVE_TUNABLES
# define GET_HWCAP_MASK() \
TUNABLE_GET (glibc, tune, hwcap_mask, uint64_t, NULL)
# else
# define GET_HWCAP_MASK() GLRO(dl_hwcap_mask)
# endif
#else
/* HWCAP_MASK is ignored in static binaries. */
# define GET_HWCAP_MASK() (0)
#endif

View File

@ -164,6 +164,7 @@ uint64_t _dl_hwcap2 __attribute__ ((nocommon));
/* The value of the FPU control word the kernel will preset in hardware. */ /* The value of the FPU control word the kernel will preset in hardware. */
fpu_control_t _dl_fpu_control = _FPU_DEFAULT; fpu_control_t _dl_fpu_control = _FPU_DEFAULT;
#if !HAVE_TUNABLES
/* This is not initialized to HWCAP_IMPORTANT, matching the definition /* This is not initialized to HWCAP_IMPORTANT, matching the definition
of _dl_important_hwcaps, below, where no hwcap strings are ever of _dl_important_hwcaps, below, where no hwcap strings are ever
used. This mask is still used to mediate the lookups in the cache used. This mask is still used to mediate the lookups in the cache
@ -171,6 +172,7 @@ fpu_control_t _dl_fpu_control = _FPU_DEFAULT;
LD_HWCAP_MASK environment variable here), there is no real point in LD_HWCAP_MASK environment variable here), there is no real point in
setting _dl_hwcap nonzero below, but we do anyway. */ setting _dl_hwcap nonzero below, but we do anyway. */
uint64_t _dl_hwcap_mask __attribute__ ((nocommon)); uint64_t _dl_hwcap_mask __attribute__ ((nocommon));
#endif
/* Prevailing state of the stack. Generally this includes PF_X, indicating it's /* Prevailing state of the stack. Generally this includes PF_X, indicating it's
* executable but this isn't true for all platforms. */ * executable but this isn't true for all platforms. */

View File

@ -159,7 +159,9 @@ struct rtld_global_ro _rtld_global_ro attribute_relro =
._dl_debug_fd = STDERR_FILENO, ._dl_debug_fd = STDERR_FILENO,
._dl_use_load_bias = -2, ._dl_use_load_bias = -2,
._dl_correct_cache_id = _DL_CACHE_DEFAULT_ID, ._dl_correct_cache_id = _DL_CACHE_DEFAULT_ID,
#if !HAVE_TUNABLES
._dl_hwcap_mask = HWCAP_IMPORTANT, ._dl_hwcap_mask = HWCAP_IMPORTANT,
#endif
._dl_lazy = 1, ._dl_lazy = 1,
._dl_fpu_control = _FPU_DEFAULT, ._dl_fpu_control = _FPU_DEFAULT,
._dl_pagesize = EXEC_PAGESIZE, ._dl_pagesize = EXEC_PAGESIZE,
@ -2402,6 +2404,7 @@ process_envvars (enum mode *modep)
_dl_show_auxv (); _dl_show_auxv ();
break; break;
#if !HAVE_TUNABLES
case 10: case 10:
/* Mask for the important hardware capabilities. */ /* Mask for the important hardware capabilities. */
if (!__libc_enable_secure if (!__libc_enable_secure
@ -2409,6 +2412,7 @@ process_envvars (enum mode *modep)
GLRO(dl_hwcap_mask) = __strtoul_internal (&envline[11], NULL, GLRO(dl_hwcap_mask) = __strtoul_internal (&envline[11], NULL,
0, 0); 0, 0);
break; break;
#endif
case 11: case 11:
/* Path where the binary is found. */ /* Path where the binary is found. */

View File

@ -515,8 +515,10 @@ struct rtld_global_ro
/* Mask for hardware capabilities that are available. */ /* Mask for hardware capabilities that are available. */
EXTERN uint64_t _dl_hwcap; EXTERN uint64_t _dl_hwcap;
#if !HAVE_TUNABLES
/* Mask for important hardware capabilities we honour. */ /* Mask for important hardware capabilities we honour. */
EXTERN uint64_t _dl_hwcap_mask; EXTERN uint64_t _dl_hwcap_mask;
#endif
#ifdef HAVE_AUX_VECTOR #ifdef HAVE_AUX_VECTOR
/* Pointer to the auxv list supplied to the program at startup. */ /* Pointer to the auxv list supplied to the program at startup. */

View File

@ -27,6 +27,7 @@
#include <sysdep.h> #include <sysdep.h>
#include <tls.h> #include <tls.h>
#include <dl-plt.h> #include <dl-plt.h>
#include <elf/dl-hwcaps.h>
/* Return nonzero iff ELF header is compatible with the running host. */ /* Return nonzero iff ELF header is compatible with the running host. */
static inline int static inline int
@ -37,7 +38,8 @@ elf_machine_matches_host (const Elf32_Ehdr *ehdr)
else if (ehdr->e_machine == EM_SPARC32PLUS) else if (ehdr->e_machine == EM_SPARC32PLUS)
{ {
#ifdef SHARED #ifdef SHARED
return GLRO(dl_hwcap) & GLRO(dl_hwcap_mask) & HWCAP_SPARC_V9; uint64_t hwcap_mask = GET_HWCAP_MASK();
return GLRO(dl_hwcap) & hwcap_mask & HWCAP_SPARC_V9;
#else #else
return GLRO(dl_hwcap) & HWCAP_SPARC_V9; return GLRO(dl_hwcap) & HWCAP_SPARC_V9;
#endif #endif

View File

@ -316,7 +316,11 @@ no_cpuid:
/* Reuse dl_platform, dl_hwcap and dl_hwcap_mask for x86. */ /* Reuse dl_platform, dl_hwcap and dl_hwcap_mask for x86. */
GLRO(dl_platform) = NULL; GLRO(dl_platform) = NULL;
GLRO(dl_hwcap) = 0; GLRO(dl_hwcap) = 0;
#if !HAVE_TUNABLES
/* The glibc.tune.hwcap_mask tunable is initialized already, so no need to do
this. */
GLRO(dl_hwcap_mask) = HWCAP_IMPORTANT; GLRO(dl_hwcap_mask) = HWCAP_IMPORTANT;
#endif
# ifdef __x86_64__ # ifdef __x86_64__
if (cpu_features->kind == arch_kind_intel) if (cpu_features->kind == arch_kind_intel)