Feedback from the kernel team suggests that it's best to only use HWCAPs
rather than also use low-level checks as done by has_lse128() and has_rcpc3().
So change these to just use HWCAPs which simplifies the code and speeds up
ifunc selection by avoiding expensive system register accesses.

libatomic:
        * config/linux/aarch64/host-config.h (has_lse2): Mark unused arg.
        (has_lse128): Change to use HWCAPs and check size of struct.
        (has_rcpc3): Likewise.

---

diff --git a/libatomic/config/linux/aarch64/host-config.h 
b/libatomic/config/linux/aarch64/host-config.h
index 
7f91528de5b2d04c4cda0a29622b32cdb1b442aa..78f56bad5aee39afc613836ebaea66fe6cf76790
 100644
--- a/libatomic/config/linux/aarch64/host-config.h
+++ b/libatomic/config/linux/aarch64/host-config.h
@@ -90,7 +90,7 @@ typedef struct __ifunc_arg_t {
 #define MIDR_PARTNUM(midr)     (((midr) >> 4) & 0xfff)
 
 static inline bool
-has_lse2 (unsigned long hwcap, const __ifunc_arg_t *features)
+has_lse2 (unsigned long hwcap, const __ifunc_arg_t *features UNUSED)
 {
   /* Check for LSE2.  */
   if (hwcap & HWCAP_USCAT)
@@ -109,50 +109,23 @@ has_lse2 (unsigned long hwcap, const __ifunc_arg_t 
*features)
   return false;
 }
 
-/* LSE128 atomic support encoded in ID_AA64ISAR0_EL1.Atomic, bits[23:20].
-   The minimum value for LSE128 is 0b0011.  */
-
-#define AT_FEAT_FIELD(isar0)   (((isar0) >> 20) & 15)
-
 static inline bool
 has_lse128 (unsigned long hwcap, const __ifunc_arg_t *features)
 {
-  if (hwcap & _IFUNC_ARG_HWCAP && features->_hwcap2 & HWCAP2_LSE128)
-    return true;
-
-  /* If LSE2 and CPUID are supported, check for LSE128.  */
-  if (hwcap & HWCAP_CPUID && hwcap & HWCAP_USCAT)
-    {
-      unsigned long isar0;
-      asm volatile ("mrs %0, ID_AA64ISAR0_EL1" : "=r" (isar0));
-      return AT_FEAT_FIELD (isar0) >= 3;
-    }
-
-  return false;
+  return (hwcap & _IFUNC_ARG_HWCAP
+         && features->_size > offsetof (__ifunc_arg_t, _hwcap2)
+         && features->_hwcap2 & HWCAP2_LSE128);
 }
 
-/* LRCPC atomic support encoded in ID_AA64ISAR1_EL1.Atomic, bits[23:20].
-   The minimum value for LRCPC3 is 0b0011.  */
-
 static inline bool
 has_rcpc3 (unsigned long hwcap, const __ifunc_arg_t *features)
 {
   /* LSE2 is a prerequisite for atomic LDIAPP/STILP - check HWCAP_USCAT since
-     has_lse2 is more expensive and Neoverse N1 does not have LRCPC3. */
-  if (!(hwcap & HWCAP_USCAT))
-    return false;
-
-  if (hwcap & _IFUNC_ARG_HWCAP && features->_hwcap2 & HWCAP2_LRCPC3)
-    return true;
-
-  if (hwcap & HWCAP_CPUID)
-    {
-      unsigned long isar1;
-      asm volatile ("mrs %0, ID_AA64ISAR1_EL1" : "=r" (isar1));
-      return AT_FEAT_FIELD (isar1) >= 3;
-    }
-
-  return false;
+     has_lse2 is more expensive and Neoverse N1 does not have LRCPC3.  */
+  return (hwcap & _IFUNC_ARG_HWCAP
+         && features->_size > offsetof (__ifunc_arg_t, _hwcap2)
+         && features->_hwcap & HWCAP_USCAT
+         && features->_hwcap2 & HWCAP2_LRCPC3);
 }
 
 #endif /* HAVE_IFUNC */

Reply via email to