1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-02-03 21:52:24 +00:00

Add CPU feature checks on M1 macOS.

I booted my M1 Mac into macOS rather than Asahi for the first time in
a while, and discovered that an OS update seems to have added some
sysctl flags indicating the presence of the CPU extensions that I
previously knew of no way to check for! Added them checks to
arm_arch_queries.c, though I've also retained backwards compat with
the previous OS version which didn't have them at all.
This commit is contained in:
Simon Tatham 2022-08-16 18:39:12 +01:00
parent 840043f06e
commit fd840f0dfe
2 changed files with 27 additions and 13 deletions

View File

@ -17,10 +17,11 @@ bool platform_aes_neon_available(void)
#elif defined HWCAP2_AES #elif defined HWCAP2_AES
return getauxval(AT_HWCAP2) & HWCAP2_AES; return getauxval(AT_HWCAP2) & HWCAP2_AES;
#elif defined __APPLE__ #elif defined __APPLE__
/* M1 macOS defines no optional sysctl flag indicating presence of SysctlResult res = test_sysctl_flag("hw.optional.arm.FEAT_AES");
* the AES extension, which I assume to be because it's always /* Older M1 macOS didn't provide this flag, but as far as I know
* present */ * implemented the crypto extension anyway, so treat 'feature
return true; * missing' as 'implemented' */
return res != SYSCTL_OFF;
#else #else
return false; return false;
#endif #endif
@ -33,8 +34,9 @@ bool platform_sha256_neon_available(void)
#elif defined HWCAP2_SHA2 #elif defined HWCAP2_SHA2
return getauxval(AT_HWCAP2) & HWCAP2_SHA2; return getauxval(AT_HWCAP2) & HWCAP2_SHA2;
#elif defined __APPLE__ #elif defined __APPLE__
/* Assume always present on M1 macOS, similarly to AES */ SysctlResult res = test_sysctl_flag("hw.optional.arm.FEAT_SHA256");
return true; /* As above, treat 'missing' as enabled */
return res != SYSCTL_OFF;
#else #else
return false; return false;
#endif #endif
@ -47,8 +49,9 @@ bool platform_sha1_neon_available(void)
#elif defined HWCAP2_SHA1 #elif defined HWCAP2_SHA1
return getauxval(AT_HWCAP2) & HWCAP2_SHA1; return getauxval(AT_HWCAP2) & HWCAP2_SHA1;
#elif defined __APPLE__ #elif defined __APPLE__
/* Assume always present on M1 macOS, similarly to AES */ SysctlResult res = test_sysctl_flag("hw.optional.arm.FEAT_SHA1");
return true; /* As above, treat 'missing' as enabled */
return res != SYSCTL_OFF;
#else #else
return false; return false;
#endif #endif
@ -61,7 +64,14 @@ bool platform_sha512_neon_available(void)
#elif defined HWCAP2_SHA512 #elif defined HWCAP2_SHA512
return getauxval(AT_HWCAP2) & HWCAP2_SHA512; return getauxval(AT_HWCAP2) & HWCAP2_SHA512;
#elif defined __APPLE__ #elif defined __APPLE__
return test_sysctl_flag("hw.optional.armv8_2_sha512"); /* There are two sysctl flags for this, apparently invented at
* different times. Try both, falling back to the older one. */
SysctlResult res = test_sysctl_flag("hw.optional.arm.FEAT_SHA512");
if (res != SYSCTL_MISSING)
return res == SYSCTL_ON;
res = test_sysctl_flag("hw.optional.armv8_2_sha512");
return res == SYSCTL_ON;
#else #else
return false; return false;
#endif #endif

View File

@ -49,15 +49,19 @@ static inline u_long getauxval(int which) { return 0; }
#endif /* defined __arm__ || defined __aarch64__ */ #endif /* defined __arm__ || defined __aarch64__ */
#if defined __APPLE__ #if defined __APPLE__
static inline bool test_sysctl_flag(const char *flagname) typedef enum { SYSCTL_MISSING, SYSCTL_OFF, SYSCTL_ON } SysctlResult;
static inline SysctlResult test_sysctl_flag(const char *flagname)
{ {
#if HAVE_SYSCTLBYNAME #if HAVE_SYSCTLBYNAME
int value; int value;
size_t size = sizeof(value); size_t size = sizeof(value);
return (sysctlbyname(flagname, &value, &size, NULL, 0) == 0 && if (sysctlbyname(flagname, &value, &size, NULL, 0) == 0 &&
size == sizeof(value) && value != 0); size == sizeof(value)) {
return value != 0 ? SYSCTL_ON : SYSCTL_OFF;
}
#else /* HAVE_SYSCTLBYNAME */ #else /* HAVE_SYSCTLBYNAME */
return false; return SYSCTL_MISSING;
#endif /* HAVE_SYSCTLBYNAME */ #endif /* HAVE_SYSCTLBYNAME */
} }
#endif /* defined __APPLE__ */ #endif /* defined __APPLE__ */