From 5d00f46e1527235ecd28a14c5413355c3ea66dfc Mon Sep 17 00:00:00 2001 From: Patrick Steuer Date: Thu, 18 Jul 2019 11:42:58 +0200 Subject: [PATCH] s390x assembly pack: use getauxval to detect hw capabilities if available. Signed-off-by: Patrick Steuer Reviewed-by: Richard Levitte (Merged from https://github.com/openssl/openssl/pull/9410) --- crypto/s390xcap.c | 95 +++++++++++++++++++++++++++++++---------------- 1 file changed, 63 insertions(+), 32 deletions(-) diff --git a/crypto/s390xcap.c b/crypto/s390xcap.c index 7d06695949..5123e14fa6 100644 --- a/crypto/s390xcap.c +++ b/crypto/s390xcap.c @@ -16,6 +16,13 @@ #include "internal/ctype.h" #include "s390x_arch.h" +#if defined(__GLIBC__) && defined(__GLIBC_PREREQ) +# if __GLIBC_PREREQ(2, 16) +# include +# define OSSL_IMPLEMENT_GETAUXVAL +# endif +#endif + #define LEN 128 #define STR_(S) #S #define STR(S) STR_(S) @@ -47,25 +54,26 @@ memcpy(cap, &NAME, sizeof(*cap)); \ } +#ifndef OSSL_IMPLEMENT_GETAUXVAL static sigjmp_buf ill_jmp; static void ill_handler(int sig) { siglongjmp(ill_jmp, sig); } +void OPENSSL_vx_probe(void); +#endif + static const char *env; static int parse_env(struct OPENSSL_s390xcap_st *cap); void OPENSSL_s390x_facilities(void); void OPENSSL_s390x_functions(void); -void OPENSSL_vx_probe(void); struct OPENSSL_s390xcap_st OPENSSL_s390xcap_P; void OPENSSL_cpuid_setup(void) { - sigset_t oset; - struct sigaction ill_act, oact_ill, oact_fpe; struct OPENSSL_s390xcap_st cap; if (OPENSSL_s390xcap_P.stfle[0]) @@ -74,47 +82,70 @@ void OPENSSL_cpuid_setup(void) /* set a bit that will not be tested later */ OPENSSL_s390xcap_P.stfle[0] |= S390X_CAPBIT(0); +#ifdef OSSL_IMPLEMENT_GETAUXVAL + { + const unsigned long hwcap = getauxval(AT_HWCAP); + + /* protection against missing store-facility-list-extended */ + if (hwcap & HWCAP_S390_STFLE) + OPENSSL_s390x_facilities(); + + /* protection against disabled vector facility */ + if (!(hwcap & HWCAP_S390_VX)) { + OPENSSL_s390xcap_P.stfle[2] &= ~(S390X_CAPBIT(S390X_VX) + | S390X_CAPBIT(S390X_VXD) + | S390X_CAPBIT(S390X_VXE)); + } + } +#else + { + sigset_t oset; + struct sigaction ill_act, oact_ill, oact_fpe; + + memset(&ill_act, 0, sizeof(ill_act)); + ill_act.sa_handler = ill_handler; + sigfillset(&ill_act.sa_mask); + sigdelset(&ill_act.sa_mask, SIGILL); + sigdelset(&ill_act.sa_mask, SIGFPE); + sigdelset(&ill_act.sa_mask, SIGTRAP); + + sigprocmask(SIG_SETMASK, &ill_act.sa_mask, &oset); + sigaction(SIGILL, &ill_act, &oact_ill); + sigaction(SIGFPE, &ill_act, &oact_fpe); + + /* protection against missing store-facility-list-extended */ + if (sigsetjmp(ill_jmp, 1) == 0) + OPENSSL_s390x_facilities(); + + /* protection against disabled vector facility */ + if ((OPENSSL_s390xcap_P.stfle[2] & S390X_CAPBIT(S390X_VX)) + && (sigsetjmp(ill_jmp, 1) == 0)) { + OPENSSL_vx_probe(); + } else { + OPENSSL_s390xcap_P.stfle[2] &= ~(S390X_CAPBIT(S390X_VX) + | S390X_CAPBIT(S390X_VXD) + | S390X_CAPBIT(S390X_VXE)); + } + + sigaction(SIGFPE, &oact_fpe, NULL); + sigaction(SIGILL, &oact_ill, NULL); + sigprocmask(SIG_SETMASK, &oset, NULL); + } +#endif + env = getenv("OPENSSL_s390xcap"); if (env != NULL) { if (!parse_env(&cap)) env = NULL; } - memset(&ill_act, 0, sizeof(ill_act)); - ill_act.sa_handler = ill_handler; - sigfillset(&ill_act.sa_mask); - sigdelset(&ill_act.sa_mask, SIGILL); - sigdelset(&ill_act.sa_mask, SIGFPE); - sigdelset(&ill_act.sa_mask, SIGTRAP); - sigprocmask(SIG_SETMASK, &ill_act.sa_mask, &oset); - sigaction(SIGILL, &ill_act, &oact_ill); - sigaction(SIGFPE, &ill_act, &oact_fpe); - - /* protection against missing store-facility-list-extended */ - if (sigsetjmp(ill_jmp, 1) == 0) - OPENSSL_s390x_facilities(); - if (env != NULL) { OPENSSL_s390xcap_P.stfle[0] &= cap.stfle[0]; OPENSSL_s390xcap_P.stfle[1] &= cap.stfle[1]; OPENSSL_s390xcap_P.stfle[2] &= cap.stfle[2]; } - /* protection against disabled vector facility */ - if ((OPENSSL_s390xcap_P.stfle[2] & S390X_CAPBIT(S390X_VX)) - && (sigsetjmp(ill_jmp, 1) == 0)) { - OPENSSL_vx_probe(); - } else { - OPENSSL_s390xcap_P.stfle[2] &= ~(S390X_CAPBIT(S390X_VX) - | S390X_CAPBIT(S390X_VXD) - | S390X_CAPBIT(S390X_VXE)); - } - - sigaction(SIGFPE, &oact_fpe, NULL); - sigaction(SIGILL, &oact_ill, NULL); - sigprocmask(SIG_SETMASK, &oset, NULL); - - OPENSSL_s390x_functions(); + OPENSSL_s390x_functions(); /* check OPENSSL_s390xcap_P.stfle */ if (env != NULL) { OPENSSL_s390xcap_P.kimd[0] &= cap.kimd[0]; -- 2.25.1