Wilco Dijkstra <[email protected]> writes:
> Hi Richard,
>
> I've reworded the commit message a bit:
>
> The CPU features initialization code uses CPUID registers (rather than
> HWCAP). The equality comparisons it uses are incorrect: for example FEAT_SVE
> is not set if SVE2 is available. Using HWCAPs for these is both simpler and
> correct. The initialization must also be done atomically to avoid multiple
> threads causing corruption due to non-atomic RMW accesses to the global.
Thanks, sounds good.
>> What criteria did you use for choosing whether to keep or remove
>> the system register checks?
>
> Essentially anything covered by HWCAP doesn't need an explicit check. So I
> kept
> the LS64 and PREDRES checks since they don't have a HWCAP allocated (I'm not
> entirely convinced we need these, let alone having 3 individual bits for
> LS64, but
> that's something for the ACLE spec to sort out). The goal here is to fix all
> obvious
> bugs so one can use FMV as intended.
Didn't we take the opposite approach for libatomic though?
/* LSE128 atomic support encoded in ID_AA64ISAR0_EL1.Atomic,
bits[23:20]. The expected value is 0b0011. Check that. */
#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;
/* A 0 HWCAP2_LSE128 bit may be just as much a sign of missing HWCAP2 bit
support in older kernels as it is of CPU feature absence. Try fallback
method to guarantee LSE128 is not implemented.
In the absence of HWCAP_CPUID, we are unable to check for LSE128.
If feature check available, check LSE2 prerequisite before proceeding. */
if (!(hwcap & HWCAP_CPUID) || !(hwcap & HWCAP_USCAT))
return false;
unsigned long isar0;
asm volatile ("mrs %0, ID_AA64ISAR0_EL1" : "=r" (isar0));
if (AT_FEAT_FIELD (isar0) >= 3)
return true;
return false;
}
I suppose one difference is that the libatomic code is gating a
choice between a well-defined, curated set of routines, whereas the
libgcc code is providing a general user-facing feature. So maybe
libgcc should be more conservative for that reason?
Thanks,
Richard