about summary refs log tree commit diff
path: root/sysdeps/unix/sysv/linux/s390
diff options
context:
space:
mode:
authorStefan Liebler <stli@linux.ibm.com>2023-02-02 14:57:50 +0100
committerStefan Liebler <stli@linux.ibm.com>2023-02-07 09:19:27 +0100
commit41f67ccbe92b4fd09e1062b383e55e407ae5bfa1 (patch)
treedfda0fd844157445add9ab30f59eeea659b38dcc /sysdeps/unix/sysv/linux/s390
parent0b9d2d4a76508fdcbd9f421cdd98bf324c22af3c (diff)
downloadglibc-41f67ccbe92b4fd09e1062b383e55e407ae5bfa1.tar.gz
glibc-41f67ccbe92b4fd09e1062b383e55e407ae5bfa1.tar.xz
glibc-41f67ccbe92b4fd09e1062b383e55e407ae5bfa1.zip
S390: Influence hwcaps/stfle via GLIBC_TUNABLES.
This patch enables the option to influence hwcaps and stfle bits used
by the s390 specific ifunc-resolvers.  The currently x86-specific
tunable glibc.cpu.hwcaps is also used on s390x to achieve the task. In
addition the user can also set a CPU arch-level like z13 instead of
single HWCAP and STFLE features.

Note that the tunable only handles the features which are really used
in the IFUNC-resolvers.  All others are ignored as the values are only
used inside glibc.  Thus we can influence:
- HWCAP_S390_VXRS (z13)
- HWCAP_S390_VXRS_EXT (z14)
- HWCAP_S390_VXRS_EXT2 (z15)
- STFLE_MIE3 (z15)

The influenced hwcap/stfle-bits are stored in the s390-specific
cpu_features struct which also contains reserved fields for future
usage.

The ifunc-resolvers and users of stfle bits are adjusted to use the
information from cpu_features struct.

On 31bit, the ELF_MACHINE_IRELATIVE macro is now also defined.
Otherwise the new ifunc-resolvers segfaults as they depend on
the not yet processed_rtld_global_ro@GLIBC_PRIVATE relocation.
Diffstat (limited to 'sysdeps/unix/sysv/linux/s390')
-rw-r--r--sysdeps/unix/sysv/linux/s390/sysconf.c29
1 files changed, 7 insertions, 22 deletions
diff --git a/sysdeps/unix/sysv/linux/s390/sysconf.c b/sysdeps/unix/sysv/linux/s390/sysconf.c
index 69969f78e4..45bd8bf4a1 100644
--- a/sysdeps/unix/sysv/linux/s390/sysconf.c
+++ b/sysdeps/unix/sysv/linux/s390/sysconf.c
@@ -18,6 +18,7 @@
 
 #include <unistd.h>
 #include <dl-procinfo.h>
+#include <cpu-features.h>
 
 static long int linux_sysconf (int name);
 
@@ -44,12 +45,14 @@ get_cache_info (int level, int attr, int type)
       || type < CACHE_TYPE_DATA || type > CACHE_TYPE_INSTRUCTION)
     return 0L;
 
+  const struct cpu_features *features = &GLRO(dl_s390_cpu_features);
+
   /* Check if ecag-instruction is available.
      ecag - extract CPU attribute (only in zarch; arch >= z10; in as 2.24)  */
-  if (!(GLRO (dl_hwcap) & HWCAP_S390_STFLE)
+  if (!(features->hwcap & HWCAP_S390_STFLE)
 #if !defined __s390x__
-      || !(GLRO (dl_hwcap) & HWCAP_S390_ZARCH)
-      || !(GLRO (dl_hwcap) & HWCAP_S390_HIGH_GPRS)
+      || !(features->hwcap & HWCAP_S390_ZARCH)
+      || !(features->hwcap & HWCAP_S390_HIGH_GPRS)
 #endif /* !__s390x__ */
       )
     {
@@ -62,25 +65,7 @@ get_cache_info (int level, int attr, int type)
 	return 0L;
     }
 
-  /* Store facility list and check for z10.
-     (see ifunc-resolver for details)  */
-  register unsigned long reg0 __asm__("0") = 0;
-#ifdef __s390x__
-  unsigned long stfle_bits;
-# define STFLE_Z10_MASK (1UL << (63 - 34))
-#else
-  unsigned long long stfle_bits;
-# define STFLE_Z10_MASK (1ULL << (63 - 34))
-#endif /* !__s390x__ */
-  __asm__ __volatile__(".machine push"        "\n\t"
-		       ".machinemode \"zarch_nohighgprs\"\n\t"
-		       ".machine \"z9-109\""  "\n\t"
-		       "stfle %0"             "\n\t"
-		       ".machine pop"         "\n"
-		       : "=QS" (stfle_bits), "+d" (reg0)
-		       : : "cc");
-
-  if (!(stfle_bits & STFLE_Z10_MASK))
+  if (!S390_IS_Z10 (features->stfle_bits))
     {
       /* We are at least on a z9 machine.
 	 Return 256byte for LINESIZE for L1 d/i-cache,