| lh | 9ed821d | 2023-04-07 01:36:19 -0700 | [diff] [blame] | 1 | /* | 
|  | 2 | * Copyright 2010-2022 The OpenSSL Project Authors. All Rights Reserved. | 
|  | 3 | * | 
|  | 4 | * Licensed under the OpenSSL license (the "License").  You may not use | 
|  | 5 | * this file except in compliance with the License.  You can obtain a copy | 
|  | 6 | * in the file LICENSE in the source distribution or at | 
|  | 7 | * https://www.openssl.org/source/license.html | 
|  | 8 | */ | 
|  | 9 |  | 
|  | 10 | #include <stdio.h> | 
|  | 11 | #include <stdlib.h> | 
|  | 12 | #include <string.h> | 
|  | 13 | #include <setjmp.h> | 
|  | 14 | #include <signal.h> | 
|  | 15 | #include "internal/cryptlib.h" | 
|  | 16 | #include "s390x_arch.h" | 
|  | 17 |  | 
|  | 18 | static sigjmp_buf ill_jmp; | 
|  | 19 | static void ill_handler(int sig) | 
|  | 20 | { | 
|  | 21 | siglongjmp(ill_jmp, sig); | 
|  | 22 | } | 
|  | 23 |  | 
|  | 24 | void OPENSSL_s390x_facilities(void); | 
|  | 25 | void OPENSSL_vx_probe(void); | 
|  | 26 |  | 
|  | 27 | struct OPENSSL_s390xcap_st OPENSSL_s390xcap_P; | 
|  | 28 |  | 
|  | 29 | #if defined(__GNUC__) && defined(__linux) | 
|  | 30 | __attribute__ ((visibility("hidden"))) | 
|  | 31 | #endif | 
|  | 32 | void OPENSSL_cpuid_setup(void) | 
|  | 33 | { | 
|  | 34 | sigset_t oset; | 
|  | 35 | struct sigaction ill_act, oact_ill, oact_fpe; | 
|  | 36 |  | 
|  | 37 | if (OPENSSL_s390xcap_P.stfle[0]) | 
|  | 38 | return; | 
|  | 39 |  | 
|  | 40 | /* set a bit that will not be tested later */ | 
|  | 41 | OPENSSL_s390xcap_P.stfle[0] |= S390X_CAPBIT(0); | 
|  | 42 |  | 
|  | 43 | memset(&ill_act, 0, sizeof(ill_act)); | 
|  | 44 | ill_act.sa_handler = ill_handler; | 
|  | 45 | sigfillset(&ill_act.sa_mask); | 
|  | 46 | sigdelset(&ill_act.sa_mask, SIGILL); | 
|  | 47 | sigdelset(&ill_act.sa_mask, SIGFPE); | 
|  | 48 | sigdelset(&ill_act.sa_mask, SIGTRAP); | 
|  | 49 | sigprocmask(SIG_SETMASK, &ill_act.sa_mask, &oset); | 
|  | 50 | sigaction(SIGILL, &ill_act, &oact_ill); | 
|  | 51 | sigaction(SIGFPE, &ill_act, &oact_fpe); | 
|  | 52 |  | 
|  | 53 | /* protection against missing store-facility-list-extended */ | 
|  | 54 | if (sigsetjmp(ill_jmp, 1) == 0) | 
|  | 55 | OPENSSL_s390x_facilities(); | 
|  | 56 |  | 
|  | 57 | /* protection against disabled vector facility */ | 
|  | 58 | if ((OPENSSL_s390xcap_P.stfle[2] & S390X_CAPBIT(S390X_VX)) | 
|  | 59 | && (sigsetjmp(ill_jmp, 1) == 0)) { | 
|  | 60 | OPENSSL_vx_probe(); | 
|  | 61 | } else { | 
|  | 62 | OPENSSL_s390xcap_P.stfle[2] &= ~(S390X_CAPBIT(S390X_VX) | 
|  | 63 | | S390X_CAPBIT(S390X_VXD) | 
|  | 64 | | S390X_CAPBIT(S390X_VXE)); | 
|  | 65 | } | 
|  | 66 |  | 
|  | 67 | sigaction(SIGFPE, &oact_fpe, NULL); | 
|  | 68 | sigaction(SIGILL, &oact_ill, NULL); | 
|  | 69 | sigprocmask(SIG_SETMASK, &oset, NULL); | 
|  | 70 | } |