From 8099ec746ac81115ce40893ab1696cd3fc7eb01e Mon Sep 17 00:00:00 2001 From: DJ Delorie Date: Wed, 13 Sep 2023 16:33:45 -0400 Subject: [PATCH] Add support for ppc64le hwcaps tunables Resolves: RHEL-1017 --- glibc-RHEL-1017-1.patch | 432 ++++++++++++++++++++++++ glibc-RHEL-1017-2.patch | 83 +++++ glibc-RHEL-1017-3.patch | 703 ++++++++++++++++++++++++++++++++++++++++ glibc-RHEL-1017-4.patch | 652 +++++++++++++++++++++++++++++++++++++ glibc.spec | 9 +- 5 files changed, 1878 insertions(+), 1 deletion(-) create mode 100644 glibc-RHEL-1017-1.patch create mode 100644 glibc-RHEL-1017-2.patch create mode 100644 glibc-RHEL-1017-3.patch create mode 100644 glibc-RHEL-1017-4.patch diff --git a/glibc-RHEL-1017-1.patch b/glibc-RHEL-1017-1.patch new file mode 100644 index 0000000..3db69a3 --- /dev/null +++ b/glibc-RHEL-1017-1.patch @@ -0,0 +1,432 @@ +From e4ca6de1bc5e4ba3f94cf0c501a293c5bc827b10 Mon Sep 17 00:00:00 2001 +From: Anton Blanchard +Date: Tue, 27 Jul 2021 15:47:49 +1000 +Subject: powerpc64: Replace some PPC_FEATURE_HAS_VSX with + PPC_FEATURE_ARCH_2_06 + +We use PPC_FEATURE_HAS_VSX to select a number of POWER7 optimised +functions. These functions don't use any VSX instructions, so +PPC_FEATURE_ARCH_2_06 seems like a better fit. + +Reviewed-by: Tulio Magno Quites Machado Filho + +diff --git a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +index 0acdf22ba3..32564c8f1f 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +@@ -95,7 +95,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + #endif + IFUNC_IMPL_ADD (array, i, memset, hwcap2 & PPC_FEATURE2_ARCH_2_07, + __memset_power8) +- IFUNC_IMPL_ADD (array, i, memset, hwcap & PPC_FEATURE_HAS_VSX, ++ IFUNC_IMPL_ADD (array, i, memset, hwcap & PPC_FEATURE_ARCH_2_06, + __memset_power7) + IFUNC_IMPL_ADD (array, i, memset, hwcap & PPC_FEATURE_ARCH_2_05, + __memset_power6) +@@ -139,7 +139,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + #endif + IFUNC_IMPL_ADD (array, i, strlen, hwcap2 & PPC_FEATURE2_ARCH_2_07, + __strlen_power8) +- IFUNC_IMPL_ADD (array, i, strlen, hwcap & PPC_FEATURE_HAS_VSX, ++ IFUNC_IMPL_ADD (array, i, strlen, hwcap & PPC_FEATURE_ARCH_2_06, + __strlen_power7) + IFUNC_IMPL_ADD (array, i, strlen, 1, + __strlen_ppc)) +@@ -152,7 +152,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + #endif + IFUNC_IMPL_ADD (array, i, strncmp, hwcap2 & PPC_FEATURE2_ARCH_2_07, + __strncmp_power8) +- IFUNC_IMPL_ADD (array, i, strncmp, hwcap & PPC_FEATURE_HAS_VSX, ++ IFUNC_IMPL_ADD (array, i, strncmp, hwcap & PPC_FEATURE_ARCH_2_06, + __strncmp_power7) + IFUNC_IMPL_ADD (array, i, strncmp, hwcap & PPC_FEATURE_POWER4, + __strncmp_power4) +@@ -165,7 +165,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + hwcap2 & PPC_FEATURE2_ARCH_2_07, + __strchr_power8) + IFUNC_IMPL_ADD (array, i, strchr, +- hwcap & PPC_FEATURE_HAS_VSX, ++ hwcap & PPC_FEATURE_ARCH_2_06, + __strchr_power7) + IFUNC_IMPL_ADD (array, i, strchr, 1, + __strchr_ppc)) +@@ -176,7 +176,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + hwcap2 & PPC_FEATURE2_ARCH_2_07, + __strchrnul_power8) + IFUNC_IMPL_ADD (array, i, strchrnul, +- hwcap & PPC_FEATURE_HAS_VSX, ++ hwcap & PPC_FEATURE_ARCH_2_06, + __strchrnul_power7) + IFUNC_IMPL_ADD (array, i, strchrnul, 1, + __strchrnul_ppc)) +@@ -192,7 +192,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + #endif + IFUNC_IMPL_ADD (array, i, memcmp, hwcap2 & PPC_FEATURE2_ARCH_2_07, + __memcmp_power8) +- IFUNC_IMPL_ADD (array, i, memcmp, hwcap & PPC_FEATURE_HAS_VSX, ++ IFUNC_IMPL_ADD (array, i, memcmp, hwcap & PPC_FEATURE_ARCH_2_06, + __memcmp_power7) + IFUNC_IMPL_ADD (array, i, memcmp, hwcap & PPC_FEATURE_POWER4, + __memcmp_power4) +@@ -244,7 +244,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + hwcap2 & PPC_FEATURE2_ARCH_2_07, + __memchr_power8) + IFUNC_IMPL_ADD (array, i, memchr, +- hwcap & PPC_FEATURE_HAS_VSX, ++ hwcap & PPC_FEATURE_ARCH_2_06, + __memchr_power7) + IFUNC_IMPL_ADD (array, i, memchr, 1, + __memchr_ppc)) +@@ -255,7 +255,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + hwcap2 & PPC_FEATURE2_ARCH_2_07, + __memrchr_power8) + IFUNC_IMPL_ADD (array, i, memrchr, +- hwcap & PPC_FEATURE_HAS_VSX, ++ hwcap & PPC_FEATURE_ARCH_2_06, + __memrchr_power7) + IFUNC_IMPL_ADD (array, i, memrchr, 1, + __memrchr_ppc)) +@@ -272,7 +272,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + __rawmemchr_power9) + #endif + IFUNC_IMPL_ADD (array, i, rawmemchr, +- hwcap & PPC_FEATURE_HAS_VSX, ++ hwcap & PPC_FEATURE_ARCH_2_06, + __rawmemchr_power7) + IFUNC_IMPL_ADD (array, i, rawmemchr, 1, + __rawmemchr_ppc)) +@@ -282,7 +282,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + IFUNC_IMPL_ADD (array, i, strnlen, + hwcap2 & PPC_FEATURE2_ARCH_2_07, + __strnlen_power8) +- IFUNC_IMPL_ADD (array, i, strnlen, hwcap & PPC_FEATURE_HAS_VSX, ++ IFUNC_IMPL_ADD (array, i, strnlen, hwcap & PPC_FEATURE_ARCH_2_06, + __strnlen_power7) + IFUNC_IMPL_ADD (array, i, strnlen, 1, + __strnlen_ppc)) +@@ -293,14 +293,14 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + hwcap2 & PPC_FEATURE2_ARCH_2_07, + __strcasecmp_power8) + IFUNC_IMPL_ADD (array, i, strcasecmp, +- hwcap & PPC_FEATURE_HAS_VSX, ++ hwcap & PPC_FEATURE_ARCH_2_06, + __strcasecmp_power7) + IFUNC_IMPL_ADD (array, i, strcasecmp, 1, __strcasecmp_ppc)) + + /* Support sysdeps/powerpc/powerpc64/multiarch/strcasecmp_l.c. */ + IFUNC_IMPL (i, name, strcasecmp_l, + IFUNC_IMPL_ADD (array, i, strcasecmp_l, +- hwcap & PPC_FEATURE_HAS_VSX, ++ hwcap & PPC_FEATURE_ARCH_2_06, + __strcasecmp_l_power7) + IFUNC_IMPL_ADD (array, i, strcasecmp_l, 1, + __strcasecmp_l_ppc)) +@@ -311,14 +311,14 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + hwcap2 & PPC_FEATURE2_ARCH_2_07, + __strncasecmp_power8) + IFUNC_IMPL_ADD (array, i, strncasecmp, +- hwcap & PPC_FEATURE_HAS_VSX, ++ hwcap & PPC_FEATURE_ARCH_2_06, + __strncasecmp_power7) + IFUNC_IMPL_ADD (array, i, strncasecmp, 1, __strncasecmp_ppc)) + + /* Support sysdeps/powerpc/powerpc64/multiarch/strncase_l.c. */ + IFUNC_IMPL (i, name, strncasecmp_l, + IFUNC_IMPL_ADD (array, i, strncasecmp_l, +- hwcap & PPC_FEATURE_HAS_VSX, ++ hwcap & PPC_FEATURE_ARCH_2_06, + __strncasecmp_l_power7) + IFUNC_IMPL_ADD (array, i, strncasecmp_l, 1, + __strncasecmp_l_ppc)) +@@ -329,7 +329,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + hwcap2 & PPC_FEATURE2_ARCH_2_07, + __strrchr_power8) + IFUNC_IMPL_ADD (array, i, strrchr, +- hwcap & PPC_FEATURE_HAS_VSX, ++ hwcap & PPC_FEATURE_ARCH_2_06, + __strrchr_power7) + IFUNC_IMPL_ADD (array, i, strrchr, 1, + __strrchr_ppc)) +@@ -357,7 +357,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + hwcap2 & PPC_FEATURE2_ARCH_2_07, + __strncpy_power8) + IFUNC_IMPL_ADD (array, i, strncpy, +- hwcap & PPC_FEATURE_HAS_VSX, ++ hwcap & PPC_FEATURE_ARCH_2_06, + __strncpy_power7) + IFUNC_IMPL_ADD (array, i, strncpy, 1, + __strncpy_ppc)) +@@ -374,7 +374,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + hwcap2 & PPC_FEATURE2_ARCH_2_07, + __stpncpy_power8) + IFUNC_IMPL_ADD (array, i, stpncpy, +- hwcap & PPC_FEATURE_HAS_VSX, ++ hwcap & PPC_FEATURE_ARCH_2_06, + __stpncpy_power7) + IFUNC_IMPL_ADD (array, i, stpncpy, 1, + __stpncpy_ppc)) +@@ -390,7 +390,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + hwcap2 & PPC_FEATURE2_ARCH_2_07, + __strcmp_power8) + IFUNC_IMPL_ADD (array, i, strcmp, +- hwcap & PPC_FEATURE_HAS_VSX, ++ hwcap & PPC_FEATURE_ARCH_2_06, + __strcmp_power7) + IFUNC_IMPL_ADD (array, i, strcmp, 1, + __strcmp_ppc)) +@@ -425,7 +425,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + /* Support sysdeps/powerpc/powerpc64/multiarch/strstr.c. */ + IFUNC_IMPL (i, name, strstr, + IFUNC_IMPL_ADD (array, i, strstr, +- hwcap & PPC_FEATURE_HAS_VSX, ++ hwcap & PPC_FEATURE_ARCH_2_06, + __strstr_power7) + IFUNC_IMPL_ADD (array, i, strstr, 1, + __strstr_ppc)) +diff --git a/sysdeps/powerpc/powerpc64/multiarch/memchr.c b/sysdeps/powerpc/powerpc64/multiarch/memchr.c +index 0c718d4f15..c24186689e 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/memchr.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/memchr.c +@@ -30,7 +30,7 @@ extern __typeof (__memchr) __memchr_power8 attribute_hidden; + libc_ifunc (__memchr, + (hwcap2 & PPC_FEATURE2_ARCH_2_07) + ? __memchr_power8 : +- (hwcap & PPC_FEATURE_HAS_VSX) ++ (hwcap & PPC_FEATURE_ARCH_2_06) + ? __memchr_power7 + : __memchr_ppc); + +diff --git a/sysdeps/powerpc/powerpc64/multiarch/memcmp.c b/sysdeps/powerpc/powerpc64/multiarch/memcmp.c +index 4fd089aba7..99559bce26 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/memcmp.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/memcmp.c +@@ -40,7 +40,7 @@ libc_ifunc_redirected (__redirect_memcmp, memcmp, + #endif + (hwcap2 & PPC_FEATURE2_ARCH_2_07) + ? __memcmp_power8 : +- (hwcap & PPC_FEATURE_HAS_VSX) ++ (hwcap & PPC_FEATURE_ARCH_2_06) + ? __memcmp_power7 + : (hwcap & PPC_FEATURE_POWER4) + ? __memcmp_power4 +diff --git a/sysdeps/powerpc/powerpc64/multiarch/memrchr.c b/sysdeps/powerpc/powerpc64/multiarch/memrchr.c +index e06d6468b8..16bb6f0042 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/memrchr.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/memrchr.c +@@ -30,7 +30,7 @@ extern __typeof (__memrchr) __memrchr_power8 attribute_hidden; + libc_ifunc (__memrchr, + (hwcap2 & PPC_FEATURE2_ARCH_2_07) + ? __memrchr_power8 : +- (hwcap & PPC_FEATURE_HAS_VSX) ++ (hwcap & PPC_FEATURE_ARCH_2_06) + ? __memrchr_power7 + : __memrchr_ppc); + +diff --git a/sysdeps/powerpc/powerpc64/multiarch/memset.c b/sysdeps/powerpc/powerpc64/multiarch/memset.c +index 5994bf02e6..c1aa143f60 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/memset.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/memset.c +@@ -48,7 +48,7 @@ libc_ifunc (__libc_memset, + # endif + (hwcap2 & PPC_FEATURE2_ARCH_2_07) + ? __memset_power8 : +- (hwcap & PPC_FEATURE_HAS_VSX) ++ (hwcap & PPC_FEATURE_ARCH_2_06) + ? __memset_power7 : + (hwcap & PPC_FEATURE_ARCH_2_05) + ? __memset_power6 : +diff --git a/sysdeps/powerpc/powerpc64/multiarch/rawmemchr.c b/sysdeps/powerpc/powerpc64/multiarch/rawmemchr.c +index c0ffea2b93..b5d2d3a635 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/rawmemchr.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/rawmemchr.c +@@ -41,7 +41,7 @@ libc_ifunc_redirected (__redirect___rawmemchr, __rawmemchr, + (hwcap2 & PPC_FEATURE2_ARCH_3_00) + ? __rawmemchr_power9 : + # endif +- (hwcap & PPC_FEATURE_HAS_VSX) ++ (hwcap & PPC_FEATURE_ARCH_2_06) + ? __rawmemchr_power7 + : __rawmemchr_ppc); + +diff --git a/sysdeps/powerpc/powerpc64/multiarch/stpncpy.c b/sysdeps/powerpc/powerpc64/multiarch/stpncpy.c +index bebd377fd9..e7035761a7 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/stpncpy.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/stpncpy.c +@@ -40,7 +40,7 @@ libc_ifunc_redirected (__redirect___stpncpy, __stpncpy, + # endif + (hwcap2 & PPC_FEATURE2_ARCH_2_07) + ? __stpncpy_power8 +- : (hwcap & PPC_FEATURE_HAS_VSX) ++ : (hwcap & PPC_FEATURE_ARCH_2_06) + ? __stpncpy_power7 + : __stpncpy_ppc); + weak_alias (__stpncpy, stpncpy) +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcasecmp.c b/sysdeps/powerpc/powerpc64/multiarch/strcasecmp.c +index dcd7774403..55ca6c85c4 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/strcasecmp.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/strcasecmp.c +@@ -29,7 +29,7 @@ extern __typeof (__strcasecmp) __strcasecmp_power8 attribute_hidden; + libc_ifunc (__libc_strcasecmp, + (hwcap2 & PPC_FEATURE2_ARCH_2_07) + ? __strcasecmp_power8: +- (hwcap & PPC_FEATURE_HAS_VSX) ++ (hwcap & PPC_FEATURE_ARCH_2_06) + ? __strcasecmp_power7 + : __strcasecmp_ppc); + +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcasecmp_l.c b/sysdeps/powerpc/powerpc64/multiarch/strcasecmp_l.c +index 96a70b8b11..1afee5d7fd 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/strcasecmp_l.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/strcasecmp_l.c +@@ -32,7 +32,7 @@ extern __typeof (__strcasecmp_l) __strcasecmp_l_power7 attribute_hidden; + + extern __typeof (__strcasecmp_l) __libc_strcasecmp_l; + libc_ifunc (__libc_strcasecmp_l, +- (hwcap & PPC_FEATURE_HAS_VSX) ++ (hwcap & PPC_FEATURE_ARCH_2_06) + ? __strcasecmp_l_power7 + : __strcasecmp_l_ppc); + +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strchr.c b/sysdeps/powerpc/powerpc64/multiarch/strchr.c +index ea9ac1134f..27c794c6b7 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/strchr.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/strchr.c +@@ -35,7 +35,7 @@ extern __typeof (strchr) __strchr_power8 attribute_hidden; + libc_ifunc_redirected (__redirect_strchr, strchr, + (hwcap2 & PPC_FEATURE2_ARCH_2_07) + ? __strchr_power8 : +- (hwcap & PPC_FEATURE_HAS_VSX) ++ (hwcap & PPC_FEATURE_ARCH_2_06) + ? __strchr_power7 + : __strchr_ppc); + weak_alias (strchr, index) +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strchrnul.c b/sysdeps/powerpc/powerpc64/multiarch/strchrnul.c +index 4688e7c3f0..4a07b4a242 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/strchrnul.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/strchrnul.c +@@ -30,7 +30,7 @@ extern __typeof (__strchrnul) __strchrnul_power8 attribute_hidden; + libc_ifunc (__strchrnul, + (hwcap2 & PPC_FEATURE2_ARCH_2_07) + ? __strchrnul_power8 : +- (hwcap & PPC_FEATURE_HAS_VSX) ++ (hwcap & PPC_FEATURE_ARCH_2_06) + ? __strchrnul_power7 + : __strchrnul_ppc); + +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcmp.c b/sysdeps/powerpc/powerpc64/multiarch/strcmp.c +index 72f9a639bf..4b0b25fff6 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/strcmp.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/strcmp.c +@@ -40,7 +40,7 @@ libc_ifunc_redirected (__redirect_strcmp, strcmp, + # endif + (hwcap2 & PPC_FEATURE2_ARCH_2_07) + ? __strcmp_power8 +- : (hwcap & PPC_FEATURE_HAS_VSX) ++ : (hwcap & PPC_FEATURE_ARCH_2_06) + ? __strcmp_power7 + : __strcmp_ppc); + #endif +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strlen.c b/sysdeps/powerpc/powerpc64/multiarch/strlen.c +index 109c8a90bd..0cd1c6faff 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/strlen.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/strlen.c +@@ -42,7 +42,7 @@ libc_ifunc (__libc_strlen, + # endif + (hwcap2 & PPC_FEATURE2_ARCH_2_07) + ? __strlen_power8 : +- (hwcap & PPC_FEATURE_HAS_VSX) ++ (hwcap & PPC_FEATURE_ARCH_2_06) + ? __strlen_power7 + : __strlen_ppc); + +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncase.c b/sysdeps/powerpc/powerpc64/multiarch/strncase.c +index 2013a5d75a..644046bd74 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/strncase.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/strncase.c +@@ -29,7 +29,7 @@ extern __typeof (__strncasecmp) __strncasecmp_power8 attribute_hidden; + libc_ifunc (__libc_strncasecmp, + (hwcap2 & PPC_FEATURE2_ARCH_2_07) + ? __strncasecmp_power8: +- (hwcap & PPC_FEATURE_HAS_VSX) ++ (hwcap & PPC_FEATURE_ARCH_2_06) + ? __strncasecmp_power7 + : __strncasecmp_ppc); + +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncase_l.c b/sysdeps/powerpc/powerpc64/multiarch/strncase_l.c +index cad6da302d..d2d761af72 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/strncase_l.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/strncase_l.c +@@ -34,7 +34,7 @@ extern __typeof (__strncasecmp_l) __strncasecmp_l_power7 attribute_hidden; + ifunc symbol properly. */ + extern __typeof (__strncasecmp_l) __libc_strncasecmp_l; + libc_ifunc (__libc_strncasecmp_l, +- (hwcap & PPC_FEATURE_HAS_VSX) ++ (hwcap & PPC_FEATURE_ARCH_2_06) + ? __strncasecmp_l_power7 + : __strncasecmp_l_ppc); + +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncmp.c b/sysdeps/powerpc/powerpc64/multiarch/strncmp.c +index eef524ddfb..1f689e5c05 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/strncmp.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/strncmp.c +@@ -43,7 +43,7 @@ libc_ifunc_redirected (__redirect_strncmp, strncmp, + # endif + (hwcap2 & PPC_FEATURE2_ARCH_2_07) + ? __strncmp_power8 +- : (hwcap & PPC_FEATURE_HAS_VSX) ++ : (hwcap & PPC_FEATURE_ARCH_2_06) + ? __strncmp_power7 + : (hwcap & PPC_FEATURE_POWER4) + ? __strncmp_power4 +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncpy.c b/sysdeps/powerpc/powerpc64/multiarch/strncpy.c +index 7da9def358..d4d3463bd1 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/strncpy.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/strncpy.c +@@ -43,7 +43,7 @@ libc_ifunc_redirected (__redirect_strncpy, strncpy, + # endif + (hwcap2 & PPC_FEATURE2_ARCH_2_07) + ? __strncpy_power8 +- : (hwcap & PPC_FEATURE_HAS_VSX) ++ : (hwcap & PPC_FEATURE_ARCH_2_06) + ? __strncpy_power7 + : __strncpy_ppc); + +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strnlen.c b/sysdeps/powerpc/powerpc64/multiarch/strnlen.c +index 264b7a752d..baf375a75a 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/strnlen.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/strnlen.c +@@ -31,7 +31,7 @@ extern __typeof (__strnlen) __strnlen_power8 attribute_hidden; + libc_ifunc_redirected (__redirect___strnlen, __strnlen, + (hwcap2 & PPC_FEATURE2_ARCH_2_07) + ? __strnlen_power8 : +- (hwcap & PPC_FEATURE_HAS_VSX) ++ (hwcap & PPC_FEATURE_ARCH_2_06) + ? __strnlen_power7 + : __strnlen_ppc); + weak_alias (__strnlen, strnlen) +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strrchr.c b/sysdeps/powerpc/powerpc64/multiarch/strrchr.c +index bb06b93d19..1c9eea1817 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/strrchr.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/strrchr.c +@@ -33,7 +33,7 @@ extern __typeof (strrchr) __strrchr_power8 attribute_hidden; + libc_ifunc_redirected (__redirect_strrchr, strrchr, + (hwcap2 & PPC_FEATURE2_ARCH_2_07) + ? __strrchr_power8 : +- (hwcap & PPC_FEATURE_HAS_VSX) ++ (hwcap & PPC_FEATURE_ARCH_2_06) + ? __strrchr_power7 + : __strrchr_ppc); + weak_alias (strrchr, rindex) +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strstr.c b/sysdeps/powerpc/powerpc64/multiarch/strstr.c +index bb0588844e..6582798dda 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/strstr.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/strstr.c +@@ -30,7 +30,7 @@ extern __typeof (strstr) __strstr_power7 attribute_hidden; + /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle + ifunc symbol properly. */ + libc_ifunc_redirected (__redirect_strstr, strstr, +- (hwcap & PPC_FEATURE_HAS_VSX) ++ (hwcap & PPC_FEATURE_ARCH_2_06) + ? __strstr_power7 + : __strstr_ppc); + #endif diff --git a/glibc-RHEL-1017-2.patch b/glibc-RHEL-1017-2.patch new file mode 100644 index 0000000..ef94f5b --- /dev/null +++ b/glibc-RHEL-1017-2.patch @@ -0,0 +1,83 @@ +From f2a15dd668913c5a1388ba7e1131b25162b2ea75 Mon Sep 17 00:00:00 2001 +From: Anton Blanchard +Date: Tue, 27 Jul 2021 15:47:50 +1000 +Subject: powerpc64: Check cacheline size before using optimised memset + routines + +A number of optimised memset routines assume the cacheline size is 128B, +so we better check before using them. + +Reviewed-by: Tulio Magno Quites Machado Filho + +diff --git a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +index 32564c8f1f..a3fdcd43bd 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +@@ -35,6 +35,9 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + unsigned long int hwcap = GLRO(dl_hwcap); + unsigned long int hwcap2 = GLRO(dl_hwcap2); ++#ifdef SHARED ++ int cacheline_size = GLRO(dl_cache_line_size); ++#endif + + /* hwcap contains only the latest supported ISA, the code checks which is + and fills the previous supported ones. */ +@@ -90,16 +93,21 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + IFUNC_IMPL_ADD (array, i, memset, + hwcap2 & PPC_FEATURE2_ARCH_3_1 + && hwcap2 & PPC_FEATURE2_HAS_ISEL +- && hwcap & PPC_FEATURE_HAS_VSX, ++ && hwcap & PPC_FEATURE_HAS_VSX ++ && cacheline_size == 128, + __memset_power10) + #endif +- IFUNC_IMPL_ADD (array, i, memset, hwcap2 & PPC_FEATURE2_ARCH_2_07, ++ IFUNC_IMPL_ADD (array, i, memset, hwcap2 & PPC_FEATURE2_ARCH_2_07 ++ && cacheline_size == 128, + __memset_power8) +- IFUNC_IMPL_ADD (array, i, memset, hwcap & PPC_FEATURE_ARCH_2_06, ++ IFUNC_IMPL_ADD (array, i, memset, hwcap & PPC_FEATURE_ARCH_2_06 ++ && cacheline_size == 128, + __memset_power7) +- IFUNC_IMPL_ADD (array, i, memset, hwcap & PPC_FEATURE_ARCH_2_05, ++ IFUNC_IMPL_ADD (array, i, memset, hwcap & PPC_FEATURE_ARCH_2_05 ++ && cacheline_size == 128, + __memset_power6) +- IFUNC_IMPL_ADD (array, i, memset, hwcap & PPC_FEATURE_POWER4, ++ IFUNC_IMPL_ADD (array, i, memset, hwcap & PPC_FEATURE_POWER4 ++ && cacheline_size == 128, + __memset_power4) + IFUNC_IMPL_ADD (array, i, memset, 1, __memset_ppc)) + +diff --git a/sysdeps/powerpc/powerpc64/multiarch/memset.c b/sysdeps/powerpc/powerpc64/multiarch/memset.c +index c1aa143f60..056e911699 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/memset.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/memset.c +@@ -43,16 +43,21 @@ libc_ifunc (__libc_memset, + # ifdef __LITTLE_ENDIAN__ + (hwcap2 & PPC_FEATURE2_ARCH_3_1 + && hwcap2 & PPC_FEATURE2_HAS_ISEL +- && hwcap & PPC_FEATURE_HAS_VSX) ++ && hwcap & PPC_FEATURE_HAS_VSX ++ && GLRO(dl_cache_line_size) == 128) + ? __memset_power10 : + # endif +- (hwcap2 & PPC_FEATURE2_ARCH_2_07) ++ (hwcap2 & PPC_FEATURE2_ARCH_2_07 ++ && GLRO(dl_cache_line_size) == 128) + ? __memset_power8 : +- (hwcap & PPC_FEATURE_ARCH_2_06) ++ (hwcap & PPC_FEATURE_ARCH_2_06 ++ && GLRO(dl_cache_line_size) == 128) + ? __memset_power7 : +- (hwcap & PPC_FEATURE_ARCH_2_05) ++ (hwcap & PPC_FEATURE_ARCH_2_05 ++ && GLRO(dl_cache_line_size) == 128) + ? __memset_power6 : +- (hwcap & PPC_FEATURE_POWER4) ++ (hwcap & PPC_FEATURE_POWER4 ++ && GLRO(dl_cache_line_size) == 128) + ? __memset_power4 + : __memset_ppc); + diff --git a/glibc-RHEL-1017-3.patch b/glibc-RHEL-1017-3.patch new file mode 100644 index 0000000..1f06fde --- /dev/null +++ b/glibc-RHEL-1017-3.patch @@ -0,0 +1,703 @@ +From 60b4dd25790342b40e8942e3a4115f511a6b6911 Mon Sep 17 00:00:00 2001 +From: Anton Blanchard +Date: Tue, 27 Jul 2021 15:47:51 +1000 +Subject: powerpc64: Add checks for Altivec and VSX in ifunc selection + +We'd like to support processors without Altivec or VSX, so check +the relevant hwcap bits before selecting them. + +Reviewed-by: Tulio Magno Quites Machado Filho + +diff --git a/sysdeps/powerpc/powerpc64/multiarch/bzero.c b/sysdeps/powerpc/powerpc64/multiarch/bzero.c +index 660d7dc686..c8ffbea01c 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/bzero.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/bzero.c +@@ -38,11 +38,13 @@ libc_ifunc (__bzero, + && hwcap & PPC_FEATURE_HAS_VSX) + ? __bzero_power10 : + # endif +- (hwcap2 & PPC_FEATURE2_ARCH_2_07) ++ (hwcap2 & PPC_FEATURE2_ARCH_2_07 ++ && hwcap & PPC_FEATURE_HAS_ALTIVEC) + ? __bzero_power8 : + (hwcap & PPC_FEATURE_HAS_VSX) + ? __bzero_power7 : +- (hwcap & PPC_FEATURE_ARCH_2_05) ++ (hwcap & PPC_FEATURE_ARCH_2_05 ++ && hwcap & PPC_FEATURE_HAS_ALTIVEC) + ? __bzero_power6 : + (hwcap & PPC_FEATURE_POWER4) + ? __bzero_power4 +diff --git a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +index a3fdcd43bd..c3e25c5981 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +@@ -60,9 +60,11 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + && hwcap & PPC_FEATURE_HAS_VSX, + __memcpy_power10) + #endif +- IFUNC_IMPL_ADD (array, i, memcpy, hwcap2 & PPC_FEATURE2_ARCH_2_07, ++ IFUNC_IMPL_ADD (array, i, memcpy, hwcap2 & PPC_FEATURE2_ARCH_2_07 ++ && hwcap & PPC_FEATURE_HAS_ALTIVEC, + __memcpy_power8_cached) +- IFUNC_IMPL_ADD (array, i, memcpy, hwcap & PPC_FEATURE_HAS_VSX, ++ IFUNC_IMPL_ADD (array, i, memcpy, hwcap & PPC_FEATURE_ARCH_2_06 ++ && hwcap & PPC_FEATURE_HAS_ALTIVEC, + __memcpy_power7) + IFUNC_IMPL_ADD (array, i, memcpy, hwcap & PPC_FEATURE_ARCH_2_06, + __memcpy_a2) +@@ -83,7 +85,8 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + && hwcap & PPC_FEATURE_HAS_VSX, + __memmove_power10) + #endif +- IFUNC_IMPL_ADD (array, i, memmove, hwcap & PPC_FEATURE_HAS_VSX, ++ IFUNC_IMPL_ADD (array, i, memmove, hwcap & PPC_FEATURE_ARCH_2_06 ++ && hwcap & PPC_FEATURE_HAS_ALTIVEC, + __memmove_power7) + IFUNC_IMPL_ADD (array, i, memmove, 1, __memmove_ppc)) + +@@ -98,6 +101,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + __memset_power10) + #endif + IFUNC_IMPL_ADD (array, i, memset, hwcap2 & PPC_FEATURE2_ARCH_2_07 ++ && hwcap & PPC_FEATURE_HAS_ALTIVEC + && cacheline_size == 128, + __memset_power8) + IFUNC_IMPL_ADD (array, i, memset, hwcap & PPC_FEATURE_ARCH_2_06 +@@ -114,12 +118,15 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + /* Support sysdeps/powerpc/powerpc64/multiarch/strcpy.c. */ + IFUNC_IMPL (i, name, strcpy, + #ifdef __LITTLE_ENDIAN__ +- IFUNC_IMPL_ADD (array, i, strcpy, hwcap2 & PPC_FEATURE2_ARCH_3_00, ++ IFUNC_IMPL_ADD (array, i, strcpy, hwcap2 & PPC_FEATURE2_ARCH_3_00 ++ && hwcap & PPC_FEATURE_HAS_VSX, + __strcpy_power9) + #endif +- IFUNC_IMPL_ADD (array, i, strcpy, hwcap2 & PPC_FEATURE2_ARCH_2_07, ++ IFUNC_IMPL_ADD (array, i, strcpy, hwcap2 & PPC_FEATURE2_ARCH_2_07 ++ && hwcap & PPC_FEATURE_HAS_ALTIVEC, + __strcpy_power8) +- IFUNC_IMPL_ADD (array, i, strcpy, hwcap & PPC_FEATURE_HAS_VSX, ++ IFUNC_IMPL_ADD (array, i, strcpy, hwcap & PPC_FEATURE_ARCH_2_06 ++ && hwcap & PPC_FEATURE_HAS_VSX, + __strcpy_power7) + IFUNC_IMPL_ADD (array, i, strcpy, 1, + __strcpy_ppc)) +@@ -127,12 +134,15 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + /* Support sysdeps/powerpc/powerpc64/multiarch/stpcpy.c. */ + IFUNC_IMPL (i, name, stpcpy, + #ifdef __LITTLE_ENDIAN__ +- IFUNC_IMPL_ADD (array, i, stpcpy, hwcap2 & PPC_FEATURE2_ARCH_3_00, ++ IFUNC_IMPL_ADD (array, i, stpcpy, hwcap2 & PPC_FEATURE2_ARCH_3_00 ++ && hwcap & PPC_FEATURE_HAS_VSX, + __stpcpy_power9) + #endif +- IFUNC_IMPL_ADD (array, i, stpcpy, hwcap2 & PPC_FEATURE2_ARCH_2_07, ++ IFUNC_IMPL_ADD (array, i, stpcpy, hwcap2 & PPC_FEATURE2_ARCH_2_07 ++ && hwcap & PPC_FEATURE_HAS_ALTIVEC, + __stpcpy_power8) +- IFUNC_IMPL_ADD (array, i, stpcpy, hwcap & PPC_FEATURE_HAS_VSX, ++ IFUNC_IMPL_ADD (array, i, stpcpy, hwcap & PPC_FEATURE_ARCH_2_06 ++ && hwcap & PPC_FEATURE_HAS_VSX, + __stpcpy_power7) + IFUNC_IMPL_ADD (array, i, stpcpy, 1, + __stpcpy_ppc)) +@@ -140,12 +150,15 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + /* Support sysdeps/powerpc/powerpc64/multiarch/strlen.c. */ + IFUNC_IMPL (i, name, strlen, + #ifdef __LITTLE_ENDIAN__ +- IFUNC_IMPL_ADD (array, i, strlen, hwcap2 & PPC_FEATURE2_ARCH_3_1, ++ IFUNC_IMPL_ADD (array, i, strlen, hwcap2 & PPC_FEATURE2_ARCH_3_1 ++ && hwcap & PPC_FEATURE_HAS_VSX, + __strlen_power10) +- IFUNC_IMPL_ADD (array, i, strlen, hwcap2 & PPC_FEATURE2_ARCH_3_00, ++ IFUNC_IMPL_ADD (array, i, strlen, hwcap2 & PPC_FEATURE2_ARCH_3_00 ++ && hwcap & PPC_FEATURE_HAS_VSX, + __strlen_power9) + #endif +- IFUNC_IMPL_ADD (array, i, strlen, hwcap2 & PPC_FEATURE2_ARCH_2_07, ++ IFUNC_IMPL_ADD (array, i, strlen, hwcap2 & PPC_FEATURE2_ARCH_2_07 ++ && hwcap & PPC_FEATURE_HAS_ALTIVEC, + __strlen_power8) + IFUNC_IMPL_ADD (array, i, strlen, hwcap & PPC_FEATURE_ARCH_2_06, + __strlen_power7) +@@ -155,7 +168,8 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + /* Support sysdeps/powerpc/powerpc64/multiarch/strncmp.c. */ + IFUNC_IMPL (i, name, strncmp, + #ifdef __LITTLE_ENDIAN__ +- IFUNC_IMPL_ADD (array, i, strncmp, hwcap2 & PPC_FEATURE2_ARCH_3_00, ++ IFUNC_IMPL_ADD (array, i, strncmp, hwcap2 & PPC_FEATURE2_ARCH_3_00 ++ && hwcap & PPC_FEATURE_HAS_ALTIVEC, + __strncmp_power9) + #endif + IFUNC_IMPL_ADD (array, i, strncmp, hwcap2 & PPC_FEATURE2_ARCH_2_07, +@@ -170,7 +184,8 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + /* Support sysdeps/powerpc/powerpc64/multiarch/strchr.c. */ + IFUNC_IMPL (i, name, strchr, + IFUNC_IMPL_ADD (array, i, strchr, +- hwcap2 & PPC_FEATURE2_ARCH_2_07, ++ hwcap2 & PPC_FEATURE2_ARCH_2_07 ++ && hwcap & PPC_FEATURE_HAS_ALTIVEC, + __strchr_power8) + IFUNC_IMPL_ADD (array, i, strchr, + hwcap & PPC_FEATURE_ARCH_2_06, +@@ -181,7 +196,8 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + /* Support sysdeps/powerpc/powerpc64/multiarch/strchrnul.c. */ + IFUNC_IMPL (i, name, strchrnul, + IFUNC_IMPL_ADD (array, i, strchrnul, +- hwcap2 & PPC_FEATURE2_ARCH_2_07, ++ hwcap2 & PPC_FEATURE2_ARCH_2_07 ++ && hwcap & PPC_FEATURE_HAS_ALTIVEC, + __strchrnul_power8) + IFUNC_IMPL_ADD (array, i, strchrnul, + hwcap & PPC_FEATURE_ARCH_2_06, +@@ -198,7 +214,8 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + && hwcap & PPC_FEATURE_HAS_VSX, + __memcmp_power10) + #endif +- IFUNC_IMPL_ADD (array, i, memcmp, hwcap2 & PPC_FEATURE2_ARCH_2_07, ++ IFUNC_IMPL_ADD (array, i, memcmp, hwcap2 & PPC_FEATURE2_ARCH_2_07 ++ && hwcap & PPC_FEATURE_HAS_ALTIVEC, + __memcmp_power8) + IFUNC_IMPL_ADD (array, i, memcmp, hwcap & PPC_FEATURE_ARCH_2_06, + __memcmp_power7) +@@ -215,11 +232,13 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + && hwcap & PPC_FEATURE_HAS_VSX, + __bzero_power10) + #endif +- IFUNC_IMPL_ADD (array, i, bzero, hwcap2 & PPC_FEATURE2_ARCH_2_07, ++ IFUNC_IMPL_ADD (array, i, bzero, hwcap2 & PPC_FEATURE2_ARCH_2_07 ++ && hwcap & PPC_FEATURE_HAS_ALTIVEC, + __bzero_power8) + IFUNC_IMPL_ADD (array, i, bzero, hwcap & PPC_FEATURE_HAS_VSX, + __bzero_power7) +- IFUNC_IMPL_ADD (array, i, bzero, hwcap & PPC_FEATURE_ARCH_2_05, ++ IFUNC_IMPL_ADD (array, i, bzero, hwcap & PPC_FEATURE_ARCH_2_05 ++ && hwcap & PPC_FEATURE_HAS_ALTIVEC, + __bzero_power6) + IFUNC_IMPL_ADD (array, i, bzero, hwcap & PPC_FEATURE_POWER4, + __bzero_power4) +@@ -241,7 +260,8 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + /* Support sysdeps/powerpc/powerpc64/multiarch/mempcpy.c. */ + IFUNC_IMPL (i, name, mempcpy, + IFUNC_IMPL_ADD (array, i, mempcpy, +- hwcap & PPC_FEATURE_HAS_VSX, ++ hwcap & PPC_FEATURE_ARCH_2_06 ++ && hwcap & PPC_FEATURE_HAS_ALTIVEC, + __mempcpy_power7) + IFUNC_IMPL_ADD (array, i, mempcpy, 1, + __mempcpy_ppc)) +@@ -249,7 +269,8 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + /* Support sysdeps/powerpc/powerpc64/multiarch/memchr.c. */ + IFUNC_IMPL (i, name, memchr, + IFUNC_IMPL_ADD (array, i, memchr, +- hwcap2 & PPC_FEATURE2_ARCH_2_07, ++ hwcap2 & PPC_FEATURE2_ARCH_2_07 ++ && hwcap & PPC_FEATURE_HAS_ALTIVEC, + __memchr_power8) + IFUNC_IMPL_ADD (array, i, memchr, + hwcap & PPC_FEATURE_ARCH_2_06, +@@ -260,7 +281,8 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + /* Support sysdeps/powerpc/powerpc64/multiarch/memrchr.c. */ + IFUNC_IMPL (i, name, memrchr, + IFUNC_IMPL_ADD (array, i, memrchr, +- hwcap2 & PPC_FEATURE2_ARCH_2_07, ++ hwcap2 & PPC_FEATURE2_ARCH_2_07 ++ && hwcap & PPC_FEATURE_HAS_ALTIVEC, + __memrchr_power8) + IFUNC_IMPL_ADD (array, i, memrchr, + hwcap & PPC_FEATURE_ARCH_2_06, +@@ -276,7 +298,8 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + && (hwcap & PPC_FEATURE_HAS_VSX), + __rawmemchr_power10) + IFUNC_IMPL_ADD (array, i, rawmemchr, +- hwcap2 & PPC_FEATURE2_ARCH_3_00, ++ hwcap2 & PPC_FEATURE2_ARCH_3_00 ++ && hwcap & PPC_FEATURE_HAS_VSX, + __rawmemchr_power9) + #endif + IFUNC_IMPL_ADD (array, i, rawmemchr, +@@ -288,7 +311,8 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + /* Support sysdeps/powerpc/powerpc64/multiarch/strnlen.c. */ + IFUNC_IMPL (i, name, strnlen, + IFUNC_IMPL_ADD (array, i, strnlen, +- hwcap2 & PPC_FEATURE2_ARCH_2_07, ++ hwcap2 & PPC_FEATURE2_ARCH_2_07 ++ && hwcap & PPC_FEATURE_HAS_ALTIVEC, + __strnlen_power8) + IFUNC_IMPL_ADD (array, i, strnlen, hwcap & PPC_FEATURE_ARCH_2_06, + __strnlen_power7) +@@ -298,7 +322,8 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + /* Support sysdeps/powerpc/powerpc64/multiarch/strcasecmp.c. */ + IFUNC_IMPL (i, name, strcasecmp, + IFUNC_IMPL_ADD (array, i, strcasecmp, +- hwcap2 & PPC_FEATURE2_ARCH_2_07, ++ hwcap2 & PPC_FEATURE2_ARCH_2_07 ++ && hwcap & PPC_FEATURE_HAS_ALTIVEC, + __strcasecmp_power8) + IFUNC_IMPL_ADD (array, i, strcasecmp, + hwcap & PPC_FEATURE_ARCH_2_06, +@@ -316,7 +341,8 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + /* Support sysdeps/powerpc/powerpc64/multiarch/strncase.c. */ + IFUNC_IMPL (i, name, strncasecmp, + IFUNC_IMPL_ADD (array, i, strncasecmp, +- hwcap2 & PPC_FEATURE2_ARCH_2_07, ++ hwcap2 & PPC_FEATURE2_ARCH_2_07 ++ && hwcap & PPC_FEATURE_HAS_ALTIVEC, + __strncasecmp_power8) + IFUNC_IMPL_ADD (array, i, strncasecmp, + hwcap & PPC_FEATURE_ARCH_2_06, +@@ -334,7 +360,8 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + /* Support sysdeps/powerpc/powerpc64/multiarch/strrchr.c. */ + IFUNC_IMPL (i, name, strrchr, + IFUNC_IMPL_ADD (array, i, strrchr, +- hwcap2 & PPC_FEATURE2_ARCH_2_07, ++ hwcap2 & PPC_FEATURE2_ARCH_2_07 ++ && hwcap & PPC_FEATURE_HAS_ALTIVEC, + __strrchr_power8) + IFUNC_IMPL_ADD (array, i, strrchr, + hwcap & PPC_FEATURE_ARCH_2_06, +@@ -345,10 +372,12 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + /* Support sysdeps/powerpc/powerpc64/multiarch/strncat.c. */ + IFUNC_IMPL (i, name, strncat, + IFUNC_IMPL_ADD (array, i, strncat, +- hwcap2 & PPC_FEATURE2_ARCH_2_07, ++ hwcap2 & PPC_FEATURE2_ARCH_2_07 ++ && hwcap & PPC_FEATURE_HAS_VSX, + __strncat_power8) + IFUNC_IMPL_ADD (array, i, strncat, +- hwcap & PPC_FEATURE_HAS_VSX, ++ hwcap & PPC_FEATURE_ARCH_2_06 ++ && hwcap & PPC_FEATURE_HAS_VSX, + __strncat_power7) + IFUNC_IMPL_ADD (array, i, strncat, 1, + __strncat_ppc)) +@@ -391,7 +420,8 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + IFUNC_IMPL (i, name, strcmp, + #ifdef __LITTLE_ENDIAN__ + IFUNC_IMPL_ADD (array, i, strcmp, +- hwcap2 & PPC_FEATURE2_ARCH_3_00, ++ hwcap2 & PPC_FEATURE2_ARCH_3_00 ++ && hwcap & PPC_FEATURE_HAS_ALTIVEC, + __strcmp_power9) + #endif + IFUNC_IMPL_ADD (array, i, strcmp, +@@ -406,10 +436,12 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + /* Support sysdeps/powerpc/powerpc64/multiarch/strcat.c. */ + IFUNC_IMPL (i, name, strcat, + IFUNC_IMPL_ADD (array, i, strcat, +- hwcap2 & PPC_FEATURE2_ARCH_2_07, ++ hwcap2 & PPC_FEATURE2_ARCH_2_07 ++ && hwcap & PPC_FEATURE_HAS_VSX, + __strcat_power8) + IFUNC_IMPL_ADD (array, i, strcat, +- hwcap & PPC_FEATURE_HAS_VSX, ++ hwcap & PPC_FEATURE_ARCH_2_06 ++ && hwcap & PPC_FEATURE_HAS_VSX, + __strcat_power7) + IFUNC_IMPL_ADD (array, i, strcat, 1, + __strcat_ppc)) +@@ -417,7 +449,8 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + /* Support sysdeps/powerpc/powerpc64/multiarch/strspn.c. */ + IFUNC_IMPL (i, name, strspn, + IFUNC_IMPL_ADD (array, i, strspn, +- hwcap2 & PPC_FEATURE2_ARCH_2_07, ++ hwcap2 & PPC_FEATURE2_ARCH_2_07 ++ && hwcap & PPC_FEATURE_HAS_VSX, + __strspn_power8) + IFUNC_IMPL_ADD (array, i, strspn, 1, + __strspn_ppc)) +@@ -425,7 +458,8 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + /* Support sysdeps/powerpc/powerpc64/multiarch/strcspn.c. */ + IFUNC_IMPL (i, name, strcspn, + IFUNC_IMPL_ADD (array, i, strcspn, +- hwcap2 & PPC_FEATURE2_ARCH_2_07, ++ hwcap2 & PPC_FEATURE2_ARCH_2_07 ++ && hwcap & PPC_FEATURE_HAS_VSX, + __strcspn_power8) + IFUNC_IMPL_ADD (array, i, strcspn, 1, + __strcspn_ppc)) +@@ -442,7 +476,8 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + /* Support sysdeps/powerpc/powerpc64/multiarch/strcasestr.c. */ + IFUNC_IMPL (i, name, strcasestr, + IFUNC_IMPL_ADD (array, i, strcasestr, +- hwcap2 & PPC_FEATURE2_ARCH_2_07, ++ hwcap2 & PPC_FEATURE2_ARCH_2_07 ++ && hwcap & PPC_FEATURE_HAS_ALTIVEC, + __strcasestr_power8) + IFUNC_IMPL_ADD (array, i, strcasestr, 1, + __strcasestr_ppc)) +diff --git a/sysdeps/powerpc/powerpc64/multiarch/memchr.c b/sysdeps/powerpc/powerpc64/multiarch/memchr.c +index c24186689e..f40013e061 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/memchr.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/memchr.c +@@ -28,7 +28,8 @@ extern __typeof (__memchr) __memchr_power8 attribute_hidden; + /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle + ifunc symbol properly. */ + libc_ifunc (__memchr, +- (hwcap2 & PPC_FEATURE2_ARCH_2_07) ++ (hwcap2 & PPC_FEATURE2_ARCH_2_07 ++ && hwcap & PPC_FEATURE_HAS_ALTIVEC) + ? __memchr_power8 : + (hwcap & PPC_FEATURE_ARCH_2_06) + ? __memchr_power7 +diff --git a/sysdeps/powerpc/powerpc64/multiarch/memcmp.c b/sysdeps/powerpc/powerpc64/multiarch/memcmp.c +index 99559bce26..89b56c103b 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/memcmp.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/memcmp.c +@@ -38,7 +38,8 @@ libc_ifunc_redirected (__redirect_memcmp, memcmp, + && hwcap & PPC_FEATURE_HAS_VSX) + ? __memcmp_power10 : + #endif +- (hwcap2 & PPC_FEATURE2_ARCH_2_07) ++ (hwcap2 & PPC_FEATURE2_ARCH_2_07 ++ && hwcap & PPC_FEATURE_HAS_ALTIVEC) + ? __memcmp_power8 : + (hwcap & PPC_FEATURE_ARCH_2_06) + ? __memcmp_power7 +diff --git a/sysdeps/powerpc/powerpc64/multiarch/memcpy.c b/sysdeps/powerpc/powerpc64/multiarch/memcpy.c +index 53ab32ef26..684ee064f2 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/memcpy.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/memcpy.c +@@ -45,9 +45,12 @@ libc_ifunc (__libc_memcpy, + (hwcap2 & PPC_FEATURE2_ARCH_3_1 && hwcap & PPC_FEATURE_HAS_VSX) + ? __memcpy_power10 : + # endif +- ((hwcap2 & PPC_FEATURE2_ARCH_2_07) && use_cached_memopt) ++ (hwcap2 & PPC_FEATURE2_ARCH_2_07 ++ && hwcap & PPC_FEATURE_HAS_ALTIVEC ++ && use_cached_memopt) + ? __memcpy_power8_cached : +- (hwcap & PPC_FEATURE_HAS_VSX) ++ (hwcap & PPC_FEATURE_ARCH_2_06 ++ && hwcap & PPC_FEATURE_HAS_ALTIVEC) + ? __memcpy_power7 : + (hwcap & PPC_FEATURE_ARCH_2_06) + ? __memcpy_a2 : +diff --git a/sysdeps/powerpc/powerpc64/multiarch/memmove.c b/sysdeps/powerpc/powerpc64/multiarch/memmove.c +index 637b2cbf7f..50253b4554 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/memmove.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/memmove.c +@@ -41,7 +41,8 @@ libc_ifunc (__libc_memmove, + && hwcap & PPC_FEATURE_HAS_VSX) + ? __memmove_power10 : + #endif +- (hwcap & PPC_FEATURE_HAS_VSX) ++ (hwcap & PPC_FEATURE_ARCH_2_06 ++ && hwcap & PPC_FEATURE_HAS_ALTIVEC) + ? __memmove_power7 + : __memmove_ppc); + +diff --git a/sysdeps/powerpc/powerpc64/multiarch/mempcpy.c b/sysdeps/powerpc/powerpc64/multiarch/mempcpy.c +index b37e0f35b5..563095a5ec 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/mempcpy.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/mempcpy.c +@@ -33,7 +33,8 @@ extern __typeof (__mempcpy) __mempcpy_power7 attribute_hidden; + /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle + ifunc symbol properly. */ + libc_ifunc_redirected (__redirect___mempcpy, __mempcpy, +- (hwcap & PPC_FEATURE_HAS_VSX) ++ (hwcap & PPC_FEATURE_ARCH_2_06 ++ && hwcap & PPC_FEATURE_HAS_ALTIVEC) + ? __mempcpy_power7 + : __mempcpy_ppc); + +diff --git a/sysdeps/powerpc/powerpc64/multiarch/memrchr.c b/sysdeps/powerpc/powerpc64/multiarch/memrchr.c +index 16bb6f0042..a8b985b06a 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/memrchr.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/memrchr.c +@@ -28,7 +28,8 @@ extern __typeof (__memrchr) __memrchr_power8 attribute_hidden; + /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle + ifunc symbol properly. */ + libc_ifunc (__memrchr, +- (hwcap2 & PPC_FEATURE2_ARCH_2_07) ++ (hwcap2 & PPC_FEATURE2_ARCH_2_07 ++ && hwcap & PPC_FEATURE_HAS_ALTIVEC) + ? __memrchr_power8 : + (hwcap & PPC_FEATURE_ARCH_2_06) + ? __memrchr_power7 +diff --git a/sysdeps/powerpc/powerpc64/multiarch/memset.c b/sysdeps/powerpc/powerpc64/multiarch/memset.c +index 056e911699..a2bc223bcc 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/memset.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/memset.c +@@ -48,6 +48,7 @@ libc_ifunc (__libc_memset, + ? __memset_power10 : + # endif + (hwcap2 & PPC_FEATURE2_ARCH_2_07 ++ && hwcap & PPC_FEATURE_HAS_ALTIVEC + && GLRO(dl_cache_line_size) == 128) + ? __memset_power8 : + (hwcap & PPC_FEATURE_ARCH_2_06 +diff --git a/sysdeps/powerpc/powerpc64/multiarch/rawmemchr.c b/sysdeps/powerpc/powerpc64/multiarch/rawmemchr.c +index b5d2d3a635..43eb459e02 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/rawmemchr.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/rawmemchr.c +@@ -38,7 +38,8 @@ libc_ifunc_redirected (__redirect___rawmemchr, __rawmemchr, + (hwcap2 & PPC_FEATURE2_ARCH_3_1) + && (hwcap & PPC_FEATURE_HAS_VSX) + ? __rawmemchr_power10 : +- (hwcap2 & PPC_FEATURE2_ARCH_3_00) ++ (hwcap2 & PPC_FEATURE2_ARCH_3_00 ++ && hwcap & PPC_FEATURE_HAS_VSX) + ? __rawmemchr_power9 : + # endif + (hwcap & PPC_FEATURE_ARCH_2_06) +diff --git a/sysdeps/powerpc/powerpc64/multiarch/stpcpy.c b/sysdeps/powerpc/powerpc64/multiarch/stpcpy.c +index d4eb4285fc..5be413405e 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/stpcpy.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/stpcpy.c +@@ -32,12 +32,15 @@ extern __typeof (__stpcpy) __stpcpy_power9 attribute_hidden; + + libc_ifunc_hidden (__stpcpy, __stpcpy, + # ifdef __LITTLE_ENDIAN__ +- (hwcap2 & PPC_FEATURE2_ARCH_3_00) ++ (hwcap2 & PPC_FEATURE2_ARCH_3_00 ++ && hwcap & PPC_FEATURE_HAS_VSX) + ? __stpcpy_power9 : + # endif +- (hwcap2 & PPC_FEATURE2_ARCH_2_07) ++ (hwcap2 & PPC_FEATURE2_ARCH_2_07 ++ && hwcap & PPC_FEATURE_HAS_ALTIVEC) + ? __stpcpy_power8 +- : (hwcap & PPC_FEATURE_HAS_VSX) ++ : (hwcap & PPC_FEATURE_ARCH_2_06 ++ && hwcap & PPC_FEATURE_HAS_VSX) + ? __stpcpy_power7 + : __stpcpy_ppc); + +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcasecmp.c b/sysdeps/powerpc/powerpc64/multiarch/strcasecmp.c +index 55ca6c85c4..21ce2d279b 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/strcasecmp.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/strcasecmp.c +@@ -27,7 +27,8 @@ extern __typeof (__strcasecmp) __strcasecmp_power7 attribute_hidden; + extern __typeof (__strcasecmp) __strcasecmp_power8 attribute_hidden; + + libc_ifunc (__libc_strcasecmp, +- (hwcap2 & PPC_FEATURE2_ARCH_2_07) ++ (hwcap2 & PPC_FEATURE2_ARCH_2_07 ++ && hwcap & PPC_FEATURE_HAS_ALTIVEC) + ? __strcasecmp_power8: + (hwcap & PPC_FEATURE_ARCH_2_06) + ? __strcasecmp_power7 +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcasestr.c b/sysdeps/powerpc/powerpc64/multiarch/strcasestr.c +index 7e4bd3b5ac..5bb3016022 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/strcasestr.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/strcasestr.c +@@ -27,7 +27,8 @@ extern __typeof (__strcasestr) __strcasestr_power8 attribute_hidden; + /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle + ifunc symbol properly. */ + libc_ifunc (__strcasestr, +- (hwcap2 & PPC_FEATURE2_ARCH_2_07) ++ (hwcap2 & PPC_FEATURE2_ARCH_2_07 ++ && hwcap & PPC_FEATURE_HAS_ALTIVEC) + ? __strcasestr_power8 + : __strcasestr_ppc); + +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcat.c b/sysdeps/powerpc/powerpc64/multiarch/strcat.c +index 6d342324c4..d8d9870824 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/strcat.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/strcat.c +@@ -28,9 +28,11 @@ extern __typeof (strcat) __strcat_power8 attribute_hidden; + # undef strcat + + libc_ifunc_redirected (__redirect_strcat, strcat, +- (hwcap2 & PPC_FEATURE2_ARCH_2_07) ++ (hwcap2 & PPC_FEATURE2_ARCH_2_07 ++ && hwcap & PPC_FEATURE_HAS_VSX) + ? __strcat_power8 +- : (hwcap & PPC_FEATURE_HAS_VSX) ++ : (hwcap & PPC_FEATURE_ARCH_2_06 ++ && hwcap & PPC_FEATURE_HAS_VSX) + ? __strcat_power7 + : __strcat_ppc); + #endif +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strchr.c b/sysdeps/powerpc/powerpc64/multiarch/strchr.c +index 27c794c6b7..62b202baf9 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/strchr.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/strchr.c +@@ -33,7 +33,8 @@ extern __typeof (strchr) __strchr_power8 attribute_hidden; + /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle + ifunc symbol properly. */ + libc_ifunc_redirected (__redirect_strchr, strchr, +- (hwcap2 & PPC_FEATURE2_ARCH_2_07) ++ (hwcap2 & PPC_FEATURE2_ARCH_2_07 ++ && hwcap & PPC_FEATURE_HAS_ALTIVEC) + ? __strchr_power8 : + (hwcap & PPC_FEATURE_ARCH_2_06) + ? __strchr_power7 +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strchrnul.c b/sysdeps/powerpc/powerpc64/multiarch/strchrnul.c +index 4a07b4a242..40e529b9d9 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/strchrnul.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/strchrnul.c +@@ -28,7 +28,8 @@ extern __typeof (__strchrnul) __strchrnul_power8 attribute_hidden; + /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle + ifunc symbol properly. */ + libc_ifunc (__strchrnul, +- (hwcap2 & PPC_FEATURE2_ARCH_2_07) ++ (hwcap2 & PPC_FEATURE2_ARCH_2_07 ++ && hwcap & PPC_FEATURE_HAS_ALTIVEC) + ? __strchrnul_power8 : + (hwcap & PPC_FEATURE_ARCH_2_06) + ? __strchrnul_power7 +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcmp.c b/sysdeps/powerpc/powerpc64/multiarch/strcmp.c +index 4b0b25fff6..8132682a99 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/strcmp.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/strcmp.c +@@ -35,7 +35,8 @@ extern __typeof (strcmp) __strcmp_power9 attribute_hidden; + + libc_ifunc_redirected (__redirect_strcmp, strcmp, + # ifdef __LITTLE_ENDIAN__ +- (hwcap2 & PPC_FEATURE2_ARCH_3_00) ++ (hwcap2 & PPC_FEATURE2_ARCH_3_00 ++ && hwcap & PPC_FEATURE_HAS_ALTIVEC) + ? __strcmp_power9 : + # endif + (hwcap2 & PPC_FEATURE2_ARCH_2_07) +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcpy.c b/sysdeps/powerpc/powerpc64/multiarch/strcpy.c +index b733fa5a23..5af1d45cc1 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/strcpy.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/strcpy.c +@@ -32,12 +32,15 @@ extern __typeof (strcpy) __strcpy_power9 attribute_hidden; + + libc_ifunc_redirected (__redirect_strcpy, strcpy, + # ifdef __LITTLE_ENDIAN__ +- (hwcap2 & PPC_FEATURE2_ARCH_3_00) ++ (hwcap2 & PPC_FEATURE2_ARCH_3_00 ++ && hwcap & PPC_FEATURE_HAS_VSX) + ? __strcpy_power9 : + # endif +- (hwcap2 & PPC_FEATURE2_ARCH_2_07) ++ (hwcap2 & PPC_FEATURE2_ARCH_2_07 ++ && hwcap & PPC_FEATURE_HAS_ALTIVEC) + ? __strcpy_power8 +- : (hwcap & PPC_FEATURE_HAS_VSX) ++ : (hwcap & PPC_FEATURE_ARCH_2_06 ++ && hwcap & PPC_FEATURE_HAS_VSX) + ? __strcpy_power7 + : __strcpy_ppc); + #endif +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcspn.c b/sysdeps/powerpc/powerpc64/multiarch/strcspn.c +index 683aa104d7..8ba01c13b1 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/strcspn.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/strcspn.c +@@ -27,7 +27,8 @@ extern __typeof (strcspn) __strcspn_ppc attribute_hidden; + extern __typeof (strcspn) __strcspn_power8 attribute_hidden; + + libc_ifunc (__libc_strcspn, +- (hwcap2 & PPC_FEATURE2_ARCH_2_07) ++ (hwcap2 & PPC_FEATURE2_ARCH_2_07 ++ && hwcap & PPC_FEATURE_HAS_VSX) + ? __strcspn_power8 + : __strcspn_ppc); + +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strlen.c b/sysdeps/powerpc/powerpc64/multiarch/strlen.c +index 0cd1c6faff..f1e28414e0 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/strlen.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/strlen.c +@@ -35,12 +35,15 @@ extern __typeof (__redirect_strlen) __strlen_power10 attribute_hidden; + + libc_ifunc (__libc_strlen, + # ifdef __LITTLE_ENDIAN__ +- (hwcap2 & PPC_FEATURE2_ARCH_3_1) ++ (hwcap2 & PPC_FEATURE2_ARCH_3_1 ++ && hwcap & PPC_FEATURE_HAS_VSX) + ? __strlen_power10 : +- (hwcap2 & PPC_FEATURE2_ARCH_3_00) ++ (hwcap2 & PPC_FEATURE2_ARCH_3_00 ++ && hwcap & PPC_FEATURE_HAS_VSX) + ? __strlen_power9 : + # endif +- (hwcap2 & PPC_FEATURE2_ARCH_2_07) ++ (hwcap2 & PPC_FEATURE2_ARCH_2_07 ++ && hwcap & PPC_FEATURE_HAS_ALTIVEC) + ? __strlen_power8 : + (hwcap & PPC_FEATURE_ARCH_2_06) + ? __strlen_power7 +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncase.c b/sysdeps/powerpc/powerpc64/multiarch/strncase.c +index 644046bd74..2802cf2c3f 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/strncase.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/strncase.c +@@ -27,7 +27,8 @@ extern __typeof (__strncasecmp) __strncasecmp_power7 attribute_hidden; + extern __typeof (__strncasecmp) __strncasecmp_power8 attribute_hidden; + + libc_ifunc (__libc_strncasecmp, +- (hwcap2 & PPC_FEATURE2_ARCH_2_07) ++ (hwcap2 & PPC_FEATURE2_ARCH_2_07 ++ && hwcap & PPC_FEATURE_HAS_ALTIVEC) + ? __strncasecmp_power8: + (hwcap & PPC_FEATURE_ARCH_2_06) + ? __strncasecmp_power7 +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncat.c b/sysdeps/powerpc/powerpc64/multiarch/strncat.c +index 0036fca91a..9ea294a72d 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/strncat.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/strncat.c +@@ -26,9 +26,11 @@ extern __typeof (strncat) __strncat_power7 attribute_hidden; + extern __typeof (strncat) __strncat_power8 attribute_hidden; + + libc_ifunc (strncat, +- (hwcap2 & PPC_FEATURE2_ARCH_2_07) ++ (hwcap2 & PPC_FEATURE2_ARCH_2_07 ++ && hwcap & PPC_FEATURE_HAS_VSX) + ? __strncat_power8 +- : (hwcap & PPC_FEATURE_HAS_VSX) ++ : (hwcap & PPC_FEATURE_ARCH_2_06 ++ && hwcap & PPC_FEATURE_HAS_VSX) + ? __strncat_power7 + : __strncat_ppc); + #endif +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncmp.c b/sysdeps/powerpc/powerpc64/multiarch/strncmp.c +index 1f689e5c05..2d21122854 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/strncmp.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/strncmp.c +@@ -38,7 +38,8 @@ extern __typeof (strncmp) __strncmp_power9 attribute_hidden; + ifunc symbol properly. */ + libc_ifunc_redirected (__redirect_strncmp, strncmp, + # ifdef __LITTLE_ENDIAN__ +- (hwcap2 & PPC_FEATURE2_ARCH_3_00) ++ (hwcap2 & PPC_FEATURE2_ARCH_3_00 ++ && hwcap & PPC_FEATURE_HAS_ALTIVEC) + ? __strncmp_power9 : + # endif + (hwcap2 & PPC_FEATURE2_ARCH_2_07) +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strnlen.c b/sysdeps/powerpc/powerpc64/multiarch/strnlen.c +index baf375a75a..e68e9d9f88 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/strnlen.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/strnlen.c +@@ -29,7 +29,8 @@ extern __typeof (__strnlen) __strnlen_power8 attribute_hidden; + # undef strnlen + # undef __strnlen + libc_ifunc_redirected (__redirect___strnlen, __strnlen, +- (hwcap2 & PPC_FEATURE2_ARCH_2_07) ++ (hwcap2 & PPC_FEATURE2_ARCH_2_07 ++ && hwcap & PPC_FEATURE_HAS_ALTIVEC) + ? __strnlen_power8 : + (hwcap & PPC_FEATURE_ARCH_2_06) + ? __strnlen_power7 +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strrchr.c b/sysdeps/powerpc/powerpc64/multiarch/strrchr.c +index 1c9eea1817..7f0cf2a1b7 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/strrchr.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/strrchr.c +@@ -31,7 +31,8 @@ extern __typeof (strrchr) __strrchr_power8 attribute_hidden; + /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle + ifunc symbol properly. */ + libc_ifunc_redirected (__redirect_strrchr, strrchr, +- (hwcap2 & PPC_FEATURE2_ARCH_2_07) ++ (hwcap2 & PPC_FEATURE2_ARCH_2_07 ++ && hwcap & PPC_FEATURE_HAS_ALTIVEC) + ? __strrchr_power8 : + (hwcap & PPC_FEATURE_ARCH_2_06) + ? __strrchr_power7 +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strspn.c b/sysdeps/powerpc/powerpc64/multiarch/strspn.c +index 70167a176b..7613ab3d55 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/strspn.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/strspn.c +@@ -27,7 +27,8 @@ extern __typeof (strspn) __strspn_ppc attribute_hidden; + extern __typeof (strspn) __strspn_power8 attribute_hidden; + + libc_ifunc (__libc_strspn, +- (hwcap2 & PPC_FEATURE2_ARCH_2_07) ++ (hwcap2 & PPC_FEATURE2_ARCH_2_07 ++ && hwcap & PPC_FEATURE_HAS_VSX) + ? __strspn_power8 + : __strspn_ppc); + diff --git a/glibc-RHEL-1017-4.patch b/glibc-RHEL-1017-4.patch new file mode 100644 index 0000000..1d327f0 --- /dev/null +++ b/glibc-RHEL-1017-4.patch @@ -0,0 +1,652 @@ +From 21841f0d562f0e944c4d267a28cc3ebd19c847e9 Mon Sep 17 00:00:00 2001 +From: Mahesh Bodapati +Date: Tue, 1 Aug 2023 07:41:17 -0500 +Subject: PowerPC: Influence cpu/arch hwcap features via GLIBC_TUNABLES + +This patch enables the option to influence hwcaps used by PowerPC. +The environment variable, GLIBC_TUNABLES=glibc.cpu.hwcaps=-xxx,yyy,-zzz...., +can be used to enable CPU/ARCH feature yyy, disable CPU/ARCH feature xxx +and zzz, where the feature name is case-sensitive and has to match the ones +mentioned in the file{sysdeps/powerpc/dl-procinfo.c}. + +Note that the hwcap tunables only used in the IFUNC selection. +Reviewed-by: Adhemerval Zanella + +[rebased to c9s by DJ] + +diff -rupN a/manual/tunables.texi b/manual/tunables.texi +--- a/manual/tunables.texi 2023-09-13 01:16:19.979884270 -0400 ++++ b/manual/tunables.texi 2023-09-13 01:17:19.217179994 -0400 +@@ -476,7 +476,10 @@ On s390x, the supported HWCAP and STFLE + @code{sysdeps/s390/cpu-features.c}. In addition the user can also set + a CPU arch-level like @code{z13} instead of single HWCAP and STFLE features. + +-This tunable is specific to i386, x86-64 and s390x. ++On powerpc, the supported HWCAP and HWCAP2 features can be found in ++@code{sysdeps/powerpc/dl-procinfo.c}. ++ ++This tunable is specific to i386, x86-64, s390x and powerpc. + @end deftp + + @deftp Tunable glibc.cpu.cached_memopt +diff -rupN a/sysdeps/powerpc/cpu-features.c b/sysdeps/powerpc/cpu-features.c +--- a/sysdeps/powerpc/cpu-features.c 2021-08-01 21:33:43.000000000 -0400 ++++ b/sysdeps/powerpc/cpu-features.c 1969-12-31 19:00:00.000000000 -0500 +@@ -1,39 +0,0 @@ +-/* Initialize cpu feature data. PowerPC version. +- Copyright (C) 2017-2021 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 +- . */ +- +-#include +-#include +- +-#if HAVE_TUNABLES +-# include +-#endif +- +-static inline void +-init_cpu_features (struct cpu_features *cpu_features) +-{ +- /* Default is to use aligned memory access on optimized function unless +- tunables is enable, since for this case user can explicit disable +- unaligned optimizations. */ +-#if HAVE_TUNABLES +- int32_t cached_memfunc = TUNABLE_GET (glibc, cpu, cached_memopt, int32_t, +- NULL); +- cpu_features->use_cached_memopt = (cached_memfunc > 0); +-#else +- cpu_features->use_cached_memopt = false; +-#endif +-} +diff -rupN a/sysdeps/powerpc/cpu-features.h b/sysdeps/powerpc/cpu-features.h +--- a/sysdeps/powerpc/cpu-features.h 2021-08-01 21:33:43.000000000 -0400 ++++ b/sysdeps/powerpc/cpu-features.h 1969-12-31 19:00:00.000000000 -0500 +@@ -1,28 +0,0 @@ +-/* Initialize cpu feature data. PowerPC version. +- Copyright (C) 2017-2021 Free Software Foundation, Inc. +- +- 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 +- . */ +- +-#ifndef __CPU_FEATURES_POWERPC_H +-# define __CPU_FEATURES_POWERPC_H +- +-#include +- +-struct cpu_features +-{ +- bool use_cached_memopt; +-}; +- +-#endif /* __CPU_FEATURES_H */ +diff -rupN a/sysdeps/powerpc/dl-tunables.list b/sysdeps/powerpc/dl-tunables.list +--- a/sysdeps/powerpc/dl-tunables.list 2021-08-01 21:33:43.000000000 -0400 ++++ b/sysdeps/powerpc/dl-tunables.list 2023-09-13 01:17:19.226180343 -0400 +@@ -24,5 +24,8 @@ glibc { + maxval: 1 + default: 0 + } ++ hwcaps { ++ type: STRING ++ } + } + } +diff -rupN a/sysdeps/powerpc/hwcapinfo.c b/sysdeps/powerpc/hwcapinfo.c +--- a/sysdeps/powerpc/hwcapinfo.c 2021-08-01 21:33:43.000000000 -0400 ++++ b/sysdeps/powerpc/hwcapinfo.c 2023-09-13 01:17:19.229180459 -0400 +@@ -19,6 +19,7 @@ + #include + #include + #include ++#include + + uint64_t __tcb_hwcap __attribute__ ((visibility ("hidden"))); + uint32_t __tcb_platform __attribute__ ((visibility ("hidden"))); +@@ -64,6 +65,9 @@ __tcb_parse_hwcap_and_convert_at_platfor + else if (h1 & PPC_FEATURE_POWER5) + h1 |= PPC_FEATURE_POWER4; + ++ uint64_t array_hwcaps[] = { h1, h2 }; ++ init_cpu_features (&GLRO(dl_powerpc_cpu_features), array_hwcaps); ++ + /* Consolidate both HWCAP and HWCAP2 into a single doubleword so that + we can read both in a single load later. */ + __tcb_hwcap = h2; +diff -rupN a/sysdeps/powerpc/powerpc32/power4/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc32/power4/multiarch/ifunc-impl-list.c +--- a/sysdeps/powerpc/powerpc32/power4/multiarch/ifunc-impl-list.c 2021-08-01 21:33:43.000000000 -0400 ++++ b/sysdeps/powerpc/powerpc32/power4/multiarch/ifunc-impl-list.c 2023-09-13 01:17:19.232180575 -0400 +@@ -21,6 +21,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 6 +@@ -33,7 +34,8 @@ __libc_ifunc_impl_list (const char *name + + size_t i = 0; + +- unsigned long int hwcap = GLRO(dl_hwcap); ++ const struct cpu_features *features = &GLRO(dl_powerpc_cpu_features); ++ unsigned long int hwcap = features->hwcap; + /* hwcap contains only the latest supported ISA, the code checks which is + and fills the previous supported ones. */ + if (hwcap & PPC_FEATURE_ARCH_2_06) +diff -rupN a/sysdeps/powerpc/powerpc32/power4/multiarch/init-arch.h b/sysdeps/powerpc/powerpc32/power4/multiarch/init-arch.h +--- a/sysdeps/powerpc/powerpc32/power4/multiarch/init-arch.h 2021-08-01 21:33:43.000000000 -0400 ++++ b/sysdeps/powerpc/powerpc32/power4/multiarch/init-arch.h 2023-09-13 01:17:19.232180575 -0400 +@@ -16,6 +16,7 @@ + . */ + + #include ++#include + + /* The code checks if _rtld_global_ro was realocated before trying to access + the dl_hwcap field. The assembly is to make the compiler not optimize the +@@ -32,11 +33,12 @@ + # define __GLRO(value) GLRO(value) + #endif + +-/* dl_hwcap contains only the latest supported ISA, the macro checks which is +- and fills the previous ones. */ ++/* Get the hardware information post the tunables set, the macro checks ++ it and fills the previous ones. */ + #define INIT_ARCH() \ +- unsigned long int hwcap = __GLRO(dl_hwcap); \ +- unsigned long int __attribute__((unused)) hwcap2 = __GLRO(dl_hwcap2); \ ++ const struct cpu_features *features = &GLRO(dl_powerpc_cpu_features); \ ++ unsigned long int hwcap = features->hwcap; \ ++ unsigned long int __attribute__((unused)) hwcap2 = features->hwcap2; \ + bool __attribute__((unused)) use_cached_memopt = \ + __GLRO(dl_powerpc_cpu_features.use_cached_memopt); \ + if (hwcap & PPC_FEATURE_ARCH_2_06) \ +diff -rupN a/sysdeps/powerpc/powerpc64/dl-machine.h b/sysdeps/powerpc/powerpc64/dl-machine.h +--- a/sysdeps/powerpc/powerpc64/dl-machine.h 2023-09-13 01:16:17.582791395 -0400 ++++ b/sysdeps/powerpc/powerpc64/dl-machine.h 2023-09-13 01:17:19.236180730 -0400 +@@ -27,7 +27,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -293,7 +292,6 @@ static inline void __attribute__ ((unuse + dl_platform_init (void) + { + __tcb_parse_hwcap_and_convert_at_platform (); +- init_cpu_features (&GLRO(dl_powerpc_cpu_features)); + } + #endif + +diff -rupN a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +--- a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c 2023-09-13 01:16:20.219893569 -0400 ++++ b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c 2023-09-13 01:19:17.169756083 -0400 +@@ -17,6 +17,7 @@ + . */ + + #include ++#include + #include + #include + #include +@@ -32,9 +33,9 @@ __libc_ifunc_impl_list (const char *name + assert (max >= MAX_IFUNC); + + size_t i = 0; +- +- unsigned long int hwcap = GLRO(dl_hwcap); +- unsigned long int hwcap2 = GLRO(dl_hwcap2); ++ const struct cpu_features *features = &GLRO(dl_powerpc_cpu_features); ++ unsigned long int hwcap = features->hwcap; ++ unsigned long int hwcap2 = features->hwcap2; + #ifdef SHARED + int cacheline_size = GLRO(dl_cache_line_size); + #endif +diff -rupN a/sysdeps/unix/sysv/linux/powerpc/Makefile b/sysdeps/unix/sysv/linux/powerpc/Makefile +--- a/sysdeps/unix/sysv/linux/powerpc/Makefile 2021-08-01 21:33:43.000000000 -0400 ++++ b/sysdeps/unix/sysv/linux/powerpc/Makefile 2023-09-13 01:17:19.243181002 -0400 +@@ -21,7 +21,12 @@ ifeq ($(subdir),misc) + sysdep_headers += bits/ppc.h + sysdep_routines += get_timebase_freq + tests-static += test-gettimebasefreq-static +-tests += $(tests-static) +-tests += test-gettimebasefreq +-tests += test-powerpc-linux-sysconf ++tests += \ ++ $(tests-static) \ ++ test-gettimebasefreq \ ++ test-powerpc-linux-sysconf \ ++ tst-hwcap-tunables \ ++ # tests ++ ++tst-hwcap-tunables-ARGS = -- $(host-test-program-cmd) + endif +diff -rupN a/sysdeps/unix/sysv/linux/powerpc/cpu-features.c b/sysdeps/unix/sysv/linux/powerpc/cpu-features.c +--- a/sysdeps/unix/sysv/linux/powerpc/cpu-features.c 1969-12-31 19:00:00.000000000 -0500 ++++ b/sysdeps/unix/sysv/linux/powerpc/cpu-features.c 2023-09-13 01:17:19.247181157 -0400 +@@ -0,0 +1,124 @@ ++/* Initialize cpu feature data. PowerPC version. ++ Copyright (C) 2017-2023 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 ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static void ++TUNABLE_CALLBACK (set_hwcaps) (tunable_val_t *valp) ++{ ++ /* The current IFUNC selection is always using the most recent ++ features which are available via AT_HWCAP or AT_HWCAP2. But in ++ some scenarios it is useful to adjust this selection. ++ ++ The environment variable: ++ ++ GLIBC_TUNABLES=glibc.cpu.hwcaps=-xxx,yyy,.... ++ ++ Can be used to enable HWCAP/HWCAP2 feature yyy, disable HWCAP/HWCAP2 ++ feature xxx, where the feature name is case-sensitive and has to match ++ the ones mentioned in the file{sysdeps/powerpc/dl-procinfo.c}. */ ++ ++ /* Copy the features from dl_powerpc_cpu_features, which contains the ++ features provided by AT_HWCAP and AT_HWCAP2. */ ++ struct cpu_features *cpu_features = &GLRO(dl_powerpc_cpu_features); ++ unsigned long int tcbv_hwcap = cpu_features->hwcap; ++ unsigned long int tcbv_hwcap2 = cpu_features->hwcap2; ++ const char *token = valp->strval; ++ do ++ { ++ const char *token_end, *feature; ++ bool disable; ++ size_t token_len, i, feature_len, offset = 0; ++ /* Find token separator or end of string. */ ++ for (token_end = token; *token_end != ','; token_end++) ++ if (*token_end == '\0') ++ break; ++ ++ /* Determine feature. */ ++ token_len = token_end - token; ++ if (*token == '-') ++ { ++ disable = true; ++ feature = token + 1; ++ feature_len = token_len - 1; ++ } ++ else ++ { ++ disable = false; ++ feature = token; ++ feature_len = token_len; ++ } ++ for (i = 0; i < array_length (hwcap_tunables); ++i) ++ { ++ const char *hwcap_name = hwcap_names + offset; ++ size_t hwcap_name_len = strlen (hwcap_name); ++ /* Check the tunable name on the supported list. */ ++ if (hwcap_name_len == feature_len ++ && memcmp (feature, hwcap_name, feature_len) == 0) ++ { ++ /* Update the hwcap and hwcap2 bits. */ ++ if (disable) ++ { ++ /* Id is 1 for hwcap2 tunable. */ ++ if (hwcap_tunables[i].id) ++ cpu_features->hwcap2 &= ~(hwcap_tunables[i].mask); ++ else ++ cpu_features->hwcap &= ~(hwcap_tunables[i].mask); ++ } ++ else ++ { ++ /* Enable the features and also check that no unsupported ++ features were enabled by user. */ ++ if (hwcap_tunables[i].id) ++ cpu_features->hwcap2 |= (tcbv_hwcap2 & hwcap_tunables[i].mask); ++ else ++ cpu_features->hwcap |= (tcbv_hwcap & hwcap_tunables[i].mask); ++ } ++ break; ++ } ++ offset += hwcap_name_len + 1; ++ } ++ token += token_len; ++ /* ... and skip token separator for next round. */ ++ if (*token == ',') ++ token++; ++ } ++ while (*token != '\0'); ++} ++ ++static inline void ++init_cpu_features (struct cpu_features *cpu_features, uint64_t hwcaps[]) ++{ ++ /* Fill the cpu_features with the supported hwcaps ++ which are set by __tcb_parse_hwcap_and_convert_at_platform. */ ++ cpu_features->hwcap = hwcaps[0]; ++ cpu_features->hwcap2 = hwcaps[1]; ++ /* Default is to use aligned memory access on optimized function unless ++ tunables is enable, since for this case user can explicit disable ++ unaligned optimizations. */ ++ int32_t cached_memfunc = TUNABLE_GET (glibc, cpu, cached_memopt, int32_t, ++ NULL); ++ cpu_features->use_cached_memopt = (cached_memfunc > 0); ++ TUNABLE_GET (glibc, cpu, hwcaps, tunable_val_t *, ++ TUNABLE_CALLBACK (set_hwcaps)); ++} +diff -rupN a/sysdeps/unix/sysv/linux/powerpc/cpu-features.h b/sysdeps/unix/sysv/linux/powerpc/cpu-features.h +--- a/sysdeps/unix/sysv/linux/powerpc/cpu-features.h 1969-12-31 19:00:00.000000000 -0500 ++++ b/sysdeps/unix/sysv/linux/powerpc/cpu-features.h 2023-09-13 01:17:19.251181312 -0400 +@@ -0,0 +1,130 @@ ++/* Initialize cpu feature data. PowerPC version. ++ Copyright (C) 2017-2023 Free Software Foundation, Inc. ++ ++ 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 ++ . */ ++ ++#ifndef __CPU_FEATURES_POWERPC_H ++# define __CPU_FEATURES_POWERPC_H ++ ++#include ++#include ++ ++struct cpu_features ++{ ++ bool use_cached_memopt; ++ unsigned long int hwcap; ++ unsigned long int hwcap2; ++}; ++ ++static const char hwcap_names[] = { ++ "4xxmac\0" ++ "altivec\0" ++ "arch_2_05\0" ++ "arch_2_06\0" ++ "archpmu\0" ++ "booke\0" ++ "cellbe\0" ++ "dfp\0" ++ "efpdouble\0" ++ "efpsingle\0" ++ "fpu\0" ++ "ic_snoop\0" ++ "mmu\0" ++ "notb\0" ++ "pa6t\0" ++ "power4\0" ++ "power5\0" ++ "power5+\0" ++ "power6x\0" ++ "ppc32\0" ++ "ppc601\0" ++ "ppc64\0" ++ "ppcle\0" ++ "smt\0" ++ "spe\0" ++ "true_le\0" ++ "ucache\0" ++ "vsx\0" ++ "arch_2_07\0" ++ "dscr\0" ++ "ebb\0" ++ "htm\0" ++ "htm-nosc\0" ++ "htm-no-suspend\0" ++ "isel\0" ++ "tar\0" ++ "vcrypto\0" ++ "arch_3_00\0" ++ "ieee128\0" ++ "darn\0" ++ "scv\0" ++ "arch_3_1\0" ++ "mma\0" ++}; ++ ++static const struct ++{ ++ unsigned int mask; ++ bool id; ++} hwcap_tunables[] = { ++ /* AT_HWCAP tunable masks. */ ++ { PPC_FEATURE_HAS_4xxMAC, 0 }, ++ { PPC_FEATURE_HAS_ALTIVEC, 0 }, ++ { PPC_FEATURE_ARCH_2_05, 0 }, ++ { PPC_FEATURE_ARCH_2_06, 0 }, ++ { PPC_FEATURE_PSERIES_PERFMON_COMPAT, 0 }, ++ { PPC_FEATURE_BOOKE, 0 }, ++ { PPC_FEATURE_CELL_BE, 0 }, ++ { PPC_FEATURE_HAS_DFP, 0 }, ++ { PPC_FEATURE_HAS_EFP_DOUBLE, 0 }, ++ { PPC_FEATURE_HAS_EFP_SINGLE, 0 }, ++ { PPC_FEATURE_HAS_FPU, 0 }, ++ { PPC_FEATURE_ICACHE_SNOOP, 0 }, ++ { PPC_FEATURE_HAS_MMU, 0 }, ++ { PPC_FEATURE_NO_TB, 0 }, ++ { PPC_FEATURE_PA6T, 0 }, ++ { PPC_FEATURE_POWER4, 0 }, ++ { PPC_FEATURE_POWER5, 0 }, ++ { PPC_FEATURE_POWER5_PLUS, 0 }, ++ { PPC_FEATURE_POWER6_EXT, 0 }, ++ { PPC_FEATURE_32, 0 }, ++ { PPC_FEATURE_601_INSTR, 0 }, ++ { PPC_FEATURE_64, 0 }, ++ { PPC_FEATURE_PPC_LE, 0 }, ++ { PPC_FEATURE_SMT, 0 }, ++ { PPC_FEATURE_HAS_SPE, 0 }, ++ { PPC_FEATURE_TRUE_LE, 0 }, ++ { PPC_FEATURE_UNIFIED_CACHE, 0 }, ++ { PPC_FEATURE_HAS_VSX, 0 }, ++ ++ /* AT_HWCAP2 tunable masks. */ ++ { PPC_FEATURE2_ARCH_2_07, 1 }, ++ { PPC_FEATURE2_HAS_DSCR, 1 }, ++ { PPC_FEATURE2_HAS_EBB, 1 }, ++ { PPC_FEATURE2_HAS_HTM, 1 }, ++ { PPC_FEATURE2_HTM_NOSC, 1 }, ++ { PPC_FEATURE2_HTM_NO_SUSPEND, 1 }, ++ { PPC_FEATURE2_HAS_ISEL, 1 }, ++ { PPC_FEATURE2_HAS_TAR, 1 }, ++ { PPC_FEATURE2_HAS_VEC_CRYPTO, 1 }, ++ { PPC_FEATURE2_ARCH_3_00, 1 }, ++ { PPC_FEATURE2_HAS_IEEE128, 1 }, ++ { PPC_FEATURE2_DARN, 1 }, ++ { PPC_FEATURE2_SCV, 1 }, ++ { PPC_FEATURE2_ARCH_3_1, 1 }, ++ { PPC_FEATURE2_MMA, 1 }, ++}; ++ ++#endif /* __CPU_FEATURES_H */ +diff -rupN a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/dl-tunables.list b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/dl-tunables.list +--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/dl-tunables.list 2023-09-13 01:16:19.989884657 -0400 ++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/dl-tunables.list 2023-09-13 01:17:19.254181428 -0400 +@@ -28,3 +28,4 @@ + @order glibc.malloc.check + @order glibc.gmon.minarcs + @order glibc.gmon.maxarcs ++@order glibc.cpu.hwcaps +diff -rupN a/sysdeps/unix/sysv/linux/powerpc/tst-hwcap-tunables.c b/sysdeps/unix/sysv/linux/powerpc/tst-hwcap-tunables.c +--- a/sysdeps/unix/sysv/linux/powerpc/tst-hwcap-tunables.c 1969-12-31 19:00:00.000000000 -0500 ++++ b/sysdeps/unix/sysv/linux/powerpc/tst-hwcap-tunables.c 2023-09-13 01:17:19.258181583 -0400 +@@ -0,0 +1,128 @@ ++/* Tests for powerpc GLIBC_TUNABLES=glibc.cpu.hwcaps filter. ++ Copyright (C) 2023 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 ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Nonzero if the program gets called via `exec'. */ ++#define CMDLINE_OPTIONS \ ++ { "restart", no_argument, &restart, 1 }, ++static int restart; ++ ++/* Hold the four initial argument used to respawn the process, plus the extra ++ '--direct', '--restart', and the function to check */ ++static char *spargs[8]; ++static int fc; ++ ++/* Called on process re-execution. */ ++_Noreturn static void ++handle_restart (int argc, char *argv[]) ++{ ++ TEST_VERIFY_EXIT (argc == 1); ++ const char *funcname = argv[0]; ++ ++ struct libc_ifunc_impl impls[32]; ++ int cnt = __libc_ifunc_impl_list ("memcpy", impls, array_length (impls)); ++ if (cnt == 0) ++ _exit (EXIT_SUCCESS); ++ TEST_VERIFY_EXIT (cnt >= 1); ++ for (int i = 0; i < cnt; i++) { ++ if (strcmp (impls[i].name, funcname) == 0) ++ { ++ TEST_COMPARE (impls[i].usable, false); ++ break; ++ } ++ } ++ ++ _exit (EXIT_SUCCESS); ++} ++ ++static void ++run_test (const char *filter, const char *funcname) ++{ ++ printf ("info: checking filter %s (expect %s ifunc selection to be removed)\n", ++ filter, funcname); ++ char *tunable = xasprintf ("GLIBC_TUNABLES=glibc.cpu.hwcaps=%s", filter); ++ char *const newenvs[] = { (char*) tunable, NULL }; ++ spargs[fc] = (char *) funcname; ++ ++ pid_t pid; ++ TEST_COMPARE (posix_spawn (&pid, spargs[0], NULL, NULL, spargs, newenvs), 0); ++ int status; ++ TEST_COMPARE (xwaitpid (pid, &status, 0), pid); ++ TEST_VERIFY (WIFEXITED (status)); ++ TEST_VERIFY (!WIFSIGNALED (status)); ++ TEST_COMPARE (WEXITSTATUS (status), 0); ++ ++ free (tunable); ++} ++ ++static int ++do_test (int argc, char *argv[]) ++{ ++ if (restart) ++ handle_restart (argc - 1, &argv[1]); ++ ++ TEST_VERIFY_EXIT (argc == 2 || argc == 5); ++ ++ int i; ++ for (i = 0; i < argc - 1; i++) ++ spargs[i] = argv[i + 1]; ++ spargs[i++] = (char *) "--direct"; ++ spargs[i++] = (char *) "--restart"; ++ fc = i++; ++ spargs[i] = NULL; ++ ++ unsigned long int hwcap = getauxval (AT_HWCAP); ++ unsigned long int hwcap2 = getauxval (AT_HWCAP2); ++ if (__WORDSIZE == 64) ++ { ++ if (hwcap2 & PPC_FEATURE2_ARCH_3_1) ++ run_test ("-arch_3_1", "__memcpy_power10"); ++ if (hwcap2 & PPC_FEATURE2_ARCH_2_07) ++ run_test ("-arch_2_07", "__memcpy_power8_cached"); ++ if (hwcap & PPC_FEATURE_ARCH_2_06) ++ run_test ("-arch_2_06", "__memcpy_power7"); ++ if (hwcap & PPC_FEATURE_ARCH_2_05) ++ run_test ("-arch_2_06,-arch_2_05","__memcpy_power6"); ++ run_test ("-arch_2_06,-arch_2_05,-power5+,-power5,-power4", "__memcpy_power4"); ++ } ++ else ++ { ++ if (hwcap & PPC_FEATURE_HAS_VSX) ++ run_test ("-vsx", "__memcpy_power7"); ++ if (hwcap & PPC_FEATURE_ARCH_2_06) ++ run_test ("-arch_2_06", "__memcpy_a2"); ++ if (hwcap & PPC_FEATURE_ARCH_2_05) ++ run_test ("-arch_2_05", "__memcpy_power6"); ++ } ++ return 0; ++} ++ ++#define TEST_FUNCTION_ARGV do_test ++#include diff --git a/glibc.spec b/glibc.spec index b055feb..16764ec 100644 --- a/glibc.spec +++ b/glibc.spec @@ -155,7 +155,7 @@ end \ Summary: The GNU libc libraries Name: glibc Version: %{glibcversion} -Release: 82%{?dist} +Release: 83%{?dist} # In general, GPLv2+ is used by programs, LGPLv2+ is used for # libraries. @@ -747,6 +747,10 @@ Patch506: glibc-rh2166710-2.patch Patch507: glibc-rh2166710-3.patch Patch508: glibc-rh2222188-6.patch Patch509: glibc-rh2213907-7.patch +Patch510: glibc-RHEL-1017-1.patch +Patch511: glibc-RHEL-1017-2.patch +Patch512: glibc-RHEL-1017-3.patch +Patch513: glibc-RHEL-1017-4.patch ############################################################################## # Continued list of core "glibc" package information: @@ -2904,6 +2908,9 @@ update_gconv_modules_cache () %endif %changelog +* Wed Sep 13 2023 DJ Delorie - 2.34-83 +- Add support for ppc64le hwcaps tunables (RHEL-1017) + * Tue Aug 15 2023 Carlos O'Donell - 2.34-82 - Fix string and memory function tuning on small systems (#2213907)