Loading crypto/ppc_arch.h +6 −0 Original line number Diff line number Diff line Loading @@ -3,8 +3,14 @@ extern unsigned int OPENSSL_ppccap_P; /* * Flags' usage can appear ambiguous, because they are set rather * to reflect OpenSSL performance preferences than actual processor * capabilities. */ # define PPC_FPU64 (1<<0) # define PPC_ALTIVEC (1<<1) # define PPC_CRYPTO207 (1<<2) # define PPC_FPU (1<<3) #endif crypto/ppccap.c +113 −21 Original line number Diff line number Diff line Loading @@ -7,6 +7,12 @@ #if defined(__linux) || defined(_AIX) # include <sys/utsname.h> #endif #if defined(_AIX53) /* defined even on post-5.3 */ # include <sys/systemcfg.h> # if !defined(__power_set) # define __power_set(a) (_system_configuration.implementation & (a)) # endif #endif #include <openssl/crypto.h> #include <openssl/bn.h> Loading Loading @@ -79,10 +85,37 @@ static void ill_handler(int sig) siglongjmp(ill_jmp, sig); } void OPENSSL_fpu_probe(void); void OPENSSL_ppc64_probe(void); void OPENSSL_altivec_probe(void); void OPENSSL_crypto207_probe(void); /* * Use a weak reference to getauxval() so we can use it if it is available * but don't break the build if it is not. Note that this is *link-time* * feature detection, not *run-time*. In other words if we link with * symbol present, it's expected to be present even at run-time. */ #if defined(__GNUC__) && __GNUC__>=2 && defined(__ELF__) extern unsigned long getauxval(unsigned long type) __attribute__ ((weak)); #else static unsigned long (*getauxval) (unsigned long) = NULL; #endif /* I wish <sys/auxv.h> was universally available */ #define HWCAP 16 /* AT_HWCAP */ #define HWCAP_PPC64 (1U << 30) #define HWCAP_ALTIVEC (1U << 28) #define HWCAP_FPU (1U << 27) #define HWCAP_POWER6_EXT (1U << 9) #define HWCAP_VSX (1U << 7) #define HWCAP2 26 /* AT_HWCAP2 */ #define HWCAP_VEC_CRYPTO (1U << 25) # if defined(__GNUC__) && __GNUC__>=2 __attribute__ ((constructor)) # endif void OPENSSL_cpuid_setup(void) { char *e; Loading @@ -94,16 +127,6 @@ void OPENSSL_cpuid_setup(void) return; trigger = 1; sigfillset(&all_masked); sigdelset(&all_masked, SIGILL); sigdelset(&all_masked, SIGTRAP); #ifdef SIGEMT sigdelset(&all_masked, SIGEMT); #endif sigdelset(&all_masked, SIGFPE); sigdelset(&all_masked, SIGBUS); sigdelset(&all_masked, SIGSEGV); if ((e = getenv("OPENSSL_ppccap"))) { OPENSSL_ppccap_P = strtoul(e, NULL, 0); return; Loading @@ -112,6 +135,8 @@ void OPENSSL_cpuid_setup(void) OPENSSL_ppccap_P = 0; #if defined(_AIX) OPENSSL_ppccap_P |= PPC_FPU; if (sizeof(size_t) == 4) { struct utsname uts; # if defined(_SC_AIX_KERNEL_BITMODE) Loading @@ -121,7 +146,69 @@ void OPENSSL_cpuid_setup(void) if (uname(&uts) != 0 || atoi(uts.version) < 6) return; } # if defined(__power_set) /* * Value used in __power_set is a single-bit 1<<n one denoting * specific processor class. Incidentally 0xffffffff<<n can be * used to denote specific processor and its successors. */ if (sizeof(size_t) == 4) { /* In 32-bit case PPC_FPU64 is always fastest [if option] */ if (__power_set(0xffffffffU<<13)) /* POWER5 and later */ OPENSSL_ppccap_P |= PPC_FPU64; } else { /* In 64-bit case PPC_FPU64 is fastest only on POWER6 */ if (__power_set(0x1U<<14)) /* POWER6 */ OPENSSL_ppccap_P |= PPC_FPU64; } if (__power_set(0xffffffffU<<14)) /* POWER6 and later */ OPENSSL_ppccap_P |= PPC_ALTIVEC; if (__power_set(0xffffffffU<<16)) /* POWER8 and later */ OPENSSL_ppccap_P |= PPC_CRYPTO207; return; # endif #endif if (getauxval != NULL) { unsigned long hwcap = getauxval(HWCAP); if (hwcap & HWCAP_FPU) { OPENSSL_ppccap_P |= PPC_FPU; if (sizeof(size_t) == 4) { /* In 32-bit case PPC_FPU64 is always fastest [if option] */ if (hwcap & HWCAP_PPC64) OPENSSL_ppccap_P |= PPC_FPU64; } else { /* In 64-bit case PPC_FPU64 is fastest only on POWER6 */ if (hwcap & HWCAP_POWER6_EXT) OPENSSL_ppccap_P |= PPC_FPU64; } } if (hwcap & HWCAP_ALTIVEC) { OPENSSL_ppccap_P |= PPC_ALTIVEC; if ((hwcap & HWCAP_VSX) && (getauxval(HWCAP2) & HWCAP_VEC_CRYPTO)) OPENSSL_ppccap_P |= PPC_CRYPTO207; } return; } sigfillset(&all_masked); sigdelset(&all_masked, SIGILL); sigdelset(&all_masked, SIGTRAP); #ifdef SIGEMT sigdelset(&all_masked, SIGEMT); #endif sigdelset(&all_masked, SIGFPE); sigdelset(&all_masked, SIGBUS); sigdelset(&all_masked, SIGSEGV); memset(&ill_act, 0, sizeof(ill_act)); ill_act.sa_handler = ill_handler; Loading @@ -130,6 +217,10 @@ void OPENSSL_cpuid_setup(void) sigprocmask(SIG_SETMASK, &ill_act.sa_mask, &oset); sigaction(SIGILL, &ill_act, &ill_oact); if (sigsetjmp(ill_jmp,1) == 0) { OPENSSL_fpu_probe(); OPENSSL_ppccap_P |= PPC_FPU; if (sizeof(size_t) == 4) { #ifdef __linux struct utsname uts; Loading @@ -144,6 +235,7 @@ void OPENSSL_cpuid_setup(void) * Wanted code detecting POWER6 CPU and setting PPC_FPU64 */ } } if (sigsetjmp(ill_jmp, 1) == 0) { OPENSSL_altivec_probe(); Loading Loading
crypto/ppc_arch.h +6 −0 Original line number Diff line number Diff line Loading @@ -3,8 +3,14 @@ extern unsigned int OPENSSL_ppccap_P; /* * Flags' usage can appear ambiguous, because they are set rather * to reflect OpenSSL performance preferences than actual processor * capabilities. */ # define PPC_FPU64 (1<<0) # define PPC_ALTIVEC (1<<1) # define PPC_CRYPTO207 (1<<2) # define PPC_FPU (1<<3) #endif
crypto/ppccap.c +113 −21 Original line number Diff line number Diff line Loading @@ -7,6 +7,12 @@ #if defined(__linux) || defined(_AIX) # include <sys/utsname.h> #endif #if defined(_AIX53) /* defined even on post-5.3 */ # include <sys/systemcfg.h> # if !defined(__power_set) # define __power_set(a) (_system_configuration.implementation & (a)) # endif #endif #include <openssl/crypto.h> #include <openssl/bn.h> Loading Loading @@ -79,10 +85,37 @@ static void ill_handler(int sig) siglongjmp(ill_jmp, sig); } void OPENSSL_fpu_probe(void); void OPENSSL_ppc64_probe(void); void OPENSSL_altivec_probe(void); void OPENSSL_crypto207_probe(void); /* * Use a weak reference to getauxval() so we can use it if it is available * but don't break the build if it is not. Note that this is *link-time* * feature detection, not *run-time*. In other words if we link with * symbol present, it's expected to be present even at run-time. */ #if defined(__GNUC__) && __GNUC__>=2 && defined(__ELF__) extern unsigned long getauxval(unsigned long type) __attribute__ ((weak)); #else static unsigned long (*getauxval) (unsigned long) = NULL; #endif /* I wish <sys/auxv.h> was universally available */ #define HWCAP 16 /* AT_HWCAP */ #define HWCAP_PPC64 (1U << 30) #define HWCAP_ALTIVEC (1U << 28) #define HWCAP_FPU (1U << 27) #define HWCAP_POWER6_EXT (1U << 9) #define HWCAP_VSX (1U << 7) #define HWCAP2 26 /* AT_HWCAP2 */ #define HWCAP_VEC_CRYPTO (1U << 25) # if defined(__GNUC__) && __GNUC__>=2 __attribute__ ((constructor)) # endif void OPENSSL_cpuid_setup(void) { char *e; Loading @@ -94,16 +127,6 @@ void OPENSSL_cpuid_setup(void) return; trigger = 1; sigfillset(&all_masked); sigdelset(&all_masked, SIGILL); sigdelset(&all_masked, SIGTRAP); #ifdef SIGEMT sigdelset(&all_masked, SIGEMT); #endif sigdelset(&all_masked, SIGFPE); sigdelset(&all_masked, SIGBUS); sigdelset(&all_masked, SIGSEGV); if ((e = getenv("OPENSSL_ppccap"))) { OPENSSL_ppccap_P = strtoul(e, NULL, 0); return; Loading @@ -112,6 +135,8 @@ void OPENSSL_cpuid_setup(void) OPENSSL_ppccap_P = 0; #if defined(_AIX) OPENSSL_ppccap_P |= PPC_FPU; if (sizeof(size_t) == 4) { struct utsname uts; # if defined(_SC_AIX_KERNEL_BITMODE) Loading @@ -121,7 +146,69 @@ void OPENSSL_cpuid_setup(void) if (uname(&uts) != 0 || atoi(uts.version) < 6) return; } # if defined(__power_set) /* * Value used in __power_set is a single-bit 1<<n one denoting * specific processor class. Incidentally 0xffffffff<<n can be * used to denote specific processor and its successors. */ if (sizeof(size_t) == 4) { /* In 32-bit case PPC_FPU64 is always fastest [if option] */ if (__power_set(0xffffffffU<<13)) /* POWER5 and later */ OPENSSL_ppccap_P |= PPC_FPU64; } else { /* In 64-bit case PPC_FPU64 is fastest only on POWER6 */ if (__power_set(0x1U<<14)) /* POWER6 */ OPENSSL_ppccap_P |= PPC_FPU64; } if (__power_set(0xffffffffU<<14)) /* POWER6 and later */ OPENSSL_ppccap_P |= PPC_ALTIVEC; if (__power_set(0xffffffffU<<16)) /* POWER8 and later */ OPENSSL_ppccap_P |= PPC_CRYPTO207; return; # endif #endif if (getauxval != NULL) { unsigned long hwcap = getauxval(HWCAP); if (hwcap & HWCAP_FPU) { OPENSSL_ppccap_P |= PPC_FPU; if (sizeof(size_t) == 4) { /* In 32-bit case PPC_FPU64 is always fastest [if option] */ if (hwcap & HWCAP_PPC64) OPENSSL_ppccap_P |= PPC_FPU64; } else { /* In 64-bit case PPC_FPU64 is fastest only on POWER6 */ if (hwcap & HWCAP_POWER6_EXT) OPENSSL_ppccap_P |= PPC_FPU64; } } if (hwcap & HWCAP_ALTIVEC) { OPENSSL_ppccap_P |= PPC_ALTIVEC; if ((hwcap & HWCAP_VSX) && (getauxval(HWCAP2) & HWCAP_VEC_CRYPTO)) OPENSSL_ppccap_P |= PPC_CRYPTO207; } return; } sigfillset(&all_masked); sigdelset(&all_masked, SIGILL); sigdelset(&all_masked, SIGTRAP); #ifdef SIGEMT sigdelset(&all_masked, SIGEMT); #endif sigdelset(&all_masked, SIGFPE); sigdelset(&all_masked, SIGBUS); sigdelset(&all_masked, SIGSEGV); memset(&ill_act, 0, sizeof(ill_act)); ill_act.sa_handler = ill_handler; Loading @@ -130,6 +217,10 @@ void OPENSSL_cpuid_setup(void) sigprocmask(SIG_SETMASK, &ill_act.sa_mask, &oset); sigaction(SIGILL, &ill_act, &ill_oact); if (sigsetjmp(ill_jmp,1) == 0) { OPENSSL_fpu_probe(); OPENSSL_ppccap_P |= PPC_FPU; if (sizeof(size_t) == 4) { #ifdef __linux struct utsname uts; Loading @@ -144,6 +235,7 @@ void OPENSSL_cpuid_setup(void) * Wanted code detecting POWER6 CPU and setting PPC_FPU64 */ } } if (sigsetjmp(ill_jmp, 1) == 0) { OPENSSL_altivec_probe(); Loading