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>
* 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
guard.
* sysdeps/unix/sysv/linux/s390/dl-procinfo.h: Likewise.

View file

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

View file

@ -24,6 +24,7 @@
#include <ldsodefs.h>
#include <dl-procinfo.h>
#include <dl-hwcaps.h>
#ifdef _DL_FIRST_PLATFORM
# 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,
size_t *max_capstrlen)
{
uint64_t hwcap_mask = GET_HWCAP_MASK();
/* 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 n, m;
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).
So there is no way to request ignoring an OS-supplied dsocap
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;
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. */
fpu_control_t _dl_fpu_control = _FPU_DEFAULT;
#if !HAVE_TUNABLES
/* This is not initialized to HWCAP_IMPORTANT, matching the definition
of _dl_important_hwcaps, below, where no hwcap strings are ever
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
setting _dl_hwcap nonzero below, but we do anyway. */
uint64_t _dl_hwcap_mask __attribute__ ((nocommon));
#endif
/* Prevailing state of the stack. Generally this includes PF_X, indicating it's
* 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_use_load_bias = -2,
._dl_correct_cache_id = _DL_CACHE_DEFAULT_ID,
#if !HAVE_TUNABLES
._dl_hwcap_mask = HWCAP_IMPORTANT,
#endif
._dl_lazy = 1,
._dl_fpu_control = _FPU_DEFAULT,
._dl_pagesize = EXEC_PAGESIZE,
@ -2402,6 +2404,7 @@ process_envvars (enum mode *modep)
_dl_show_auxv ();
break;
#if !HAVE_TUNABLES
case 10:
/* Mask for the important hardware capabilities. */
if (!__libc_enable_secure
@ -2409,6 +2412,7 @@ process_envvars (enum mode *modep)
GLRO(dl_hwcap_mask) = __strtoul_internal (&envline[11], NULL,
0, 0);
break;
#endif
case 11:
/* Path where the binary is found. */

View file

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

View file

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

View file

@ -316,7 +316,11 @@ no_cpuid:
/* Reuse dl_platform, dl_hwcap and dl_hwcap_mask for x86. */
GLRO(dl_platform) = NULL;
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;
#endif
# ifdef __x86_64__
if (cpu_features->kind == arch_kind_intel)