1238384Sjkim#include <stdio.h>
2238384Sjkim#include <stdlib.h>
3238384Sjkim#include <string.h>
4238384Sjkim#include <setjmp.h>
5238384Sjkim#include <signal.h>
6238384Sjkim
7238384Sjkimextern unsigned long OPENSSL_s390xcap_P[];
8238384Sjkim
9238384Sjkimstatic sigjmp_buf ill_jmp;
10296341Sdelphijstatic void ill_handler(int sig)
11296341Sdelphij{
12296341Sdelphij    siglongjmp(ill_jmp, sig);
13296341Sdelphij}
14238384Sjkim
15238384Sjkimunsigned long OPENSSL_s390x_facilities(void);
16238384Sjkim
17238384Sjkimvoid OPENSSL_cpuid_setup(void)
18296341Sdelphij{
19296341Sdelphij    sigset_t oset;
20296341Sdelphij    struct sigaction ill_act, oact;
21238384Sjkim
22296341Sdelphij    if (OPENSSL_s390xcap_P[0])
23296341Sdelphij        return;
24238384Sjkim
25296341Sdelphij    OPENSSL_s390xcap_P[0] = 1UL << (8 * sizeof(unsigned long) - 1);
26238384Sjkim
27296341Sdelphij    memset(&ill_act, 0, sizeof(ill_act));
28296341Sdelphij    ill_act.sa_handler = ill_handler;
29296341Sdelphij    sigfillset(&ill_act.sa_mask);
30296341Sdelphij    sigdelset(&ill_act.sa_mask, SIGILL);
31296341Sdelphij    sigdelset(&ill_act.sa_mask, SIGTRAP);
32296341Sdelphij    sigprocmask(SIG_SETMASK, &ill_act.sa_mask, &oset);
33296341Sdelphij    sigaction(SIGILL, &ill_act, &oact);
34238384Sjkim
35296341Sdelphij    /* protection against missing store-facility-list-extended */
36296341Sdelphij    if (sigsetjmp(ill_jmp, 1) == 0)
37296341Sdelphij        OPENSSL_s390x_facilities();
38238384Sjkim
39296341Sdelphij    sigaction(SIGILL, &oact, NULL);
40296341Sdelphij    sigprocmask(SIG_SETMASK, &oset, NULL);
41296341Sdelphij}
42