From 3e719c99f588095568c6cd83098c4b1364f2d8e2 Mon Sep 17 00:00:00 2001 From: Andy Polyakov Date: Tue, 19 Jan 2010 21:40:58 +0000 Subject: [PATCH] s390x assembler update: add support for run-time facility detection [from HEAD]. --- Configure | 2 +- TABLE | 2 +- crypto/aes/asm/aes-s390x.pl | 6 ++++++ crypto/s390xcap.c | 37 ++++++++++++++++++++++++++++++++++ crypto/s390xcpuid.S | 14 ++++++------- crypto/sha/asm/sha1-s390x.pl | 5 +++++ crypto/sha/asm/sha512-s390x.pl | 5 +++++ 7 files changed, 62 insertions(+), 9 deletions(-) create mode 100644 crypto/s390xcap.c diff --git a/Configure b/Configure index 5a11042916..d15b6895fc 100755 --- a/Configure +++ b/Configure @@ -133,7 +133,7 @@ my $sparcv9_asm="sparcv9cap.o sparccpuid.o:bn-sparcv9.o sparcv9-mont.o sparcv9a- my $sparcv8_asm=":sparcv8.o:des_enc-sparc.o fcrypt_b.o:::::::::::void"; my $alpha_asm="alphacpuid.o:bn_asm.o alpha-mont.o::::::::::::void"; my $mips3_asm=":bn-mips3.o::::::::::::void"; -my $s390x_asm="s390xcpuid.o:bn-s390x.o s390x-mont.o::aes-s390x.o:::sha1-s390x.o sha256-s390x.o sha512-s390x.o::rc4-s390x.o:::::void"; +my $s390x_asm="s390xcap.o s390xcpuid.o:bn-s390x.o s390x-mont.o::aes-s390x.o:::sha1-s390x.o sha256-s390x.o sha512-s390x.o::rc4-s390x.o:::::void"; my $armv4_asm=":bn_asm.o armv4-mont.o::aes_cbc.o aes-armv4.o:::sha1-armv4-large.o sha256-armv4.o sha512-armv4.o:::::::void"; my $ppc32_asm="ppccpuid.o:bn-ppc.o::aes_core.o aes_cbc.o aes-ppc.o:::sha1-ppc.o sha256-ppc.o::::::"; my $ppc64_asm="ppccpuid.o:bn-ppc.o ppc-mont.o::aes_core.o aes_cbc.o aes-ppc.o:::sha1-ppc.o sha256-ppc.o sha512-ppc.o::::::"; diff --git a/TABLE b/TABLE index 0283490e45..85c5017e59 100644 --- a/TABLE +++ b/TABLE @@ -3728,7 +3728,7 @@ $thread_cflag = -D_REENTRANT $sys_id = $lflags = -ldl $bn_ops = SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL -$cpuid_obj = s390xcpuid.o +$cpuid_obj = s390xcap.o s390xcpuid.o $bn_obj = bn-s390x.o s390x-mont.o $des_obj = $aes_obj = aes-s390x.o diff --git a/crypto/aes/asm/aes-s390x.pl b/crypto/aes/asm/aes-s390x.pl index 4b27afd92f..7e01889298 100644 --- a/crypto/aes/asm/aes-s390x.pl +++ b/crypto/aes/asm/aes-s390x.pl @@ -765,6 +765,11 @@ $code.=<<___ if (!$softonly); srl %r5,6 ar %r5,%r0 + larl %r1,OPENSSL_s390xcap_P + lg %r0,0(%r1) + tmhl %r0,0x4000 # check for message-security assist + jz .Lekey_internal + lghi %r0,0 # query capability vector la %r1,16($sp) .long 0xb92f0042 # kmc %r4,%r2 @@ -1323,6 +1328,7 @@ $code.=<<___; 4: ex $len,0($s1) j .Lcbc_dec_exit .size AES_cbc_encrypt,.-AES_cbc_encrypt +.comm OPENSSL_s390xcap_P,8,8 ___ } $code.=<<___; diff --git a/crypto/s390xcap.c b/crypto/s390xcap.c new file mode 100644 index 0000000000..ffbe0235f9 --- /dev/null +++ b/crypto/s390xcap.c @@ -0,0 +1,37 @@ +#include +#include +#include +#include +#include + +extern unsigned long OPENSSL_s390xcap_P; + +static sigjmp_buf ill_jmp; +static void ill_handler (int sig) { siglongjmp(ill_jmp,sig); } + +unsigned long OPENSSL_s390x_facilities(void); + +void OPENSSL_cpuid_setup(void) + { + sigset_t oset; + struct sigaction ill_act,oact; + + if (OPENSSL_s390xcap_P) return; + + 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,SIGTRAP); + sigprocmask(SIG_SETMASK,&ill_act.sa_mask,&oset); + sigaction (SIGILL,&ill_act,&oact); + + /* protection against missing store-facility-list-extended */ + if (sigsetjmp(ill_jmp,0) == 0) + OPENSSL_s390xcap_P = OPENSSL_s390x_facilities(); + else + OPENSSL_s390xcap_P = 1UL<<63; + + sigaction (SIGILL,&oact,NULL); + sigprocmask(SIG_SETMASK,&oset,NULL); + } diff --git a/crypto/s390xcpuid.S b/crypto/s390xcpuid.S index 8500133ad0..aa704c033a 100644 --- a/crypto/s390xcpuid.S +++ b/crypto/s390xcpuid.S @@ -1,12 +1,5 @@ .text -.globl OPENSSL_cpuid_setup -.type OPENSSL_cpuid_setup,@function -.align 16 -OPENSSL_cpuid_setup: - br %r14 # reserved for future -.size OPENSSL_cpuid_setup,.-OPENSSL_cpuid_setup - .globl OPENSSL_s390x_facilities .type OPENSSL_s390x_facilities,@function .align 16 @@ -14,6 +7,8 @@ OPENSSL_s390x_facilities: lghi %r0,0 .long 0xb2b0f010 # stfle 16(%r15) lg %r2,16(%r15) + larl %r1,OPENSSL_s390xcap_P + stg %r2,0(%r1) br %r14 .size OPENSSL_s390x_facilities,.-OPENSSL_s390x_facilities @@ -88,3 +83,8 @@ OPENSSL_cleanse: jnz .Little br %r14 .size OPENSSL_cleanse,.-OPENSSL_cleanse + +.section .init + brasl %r14,OPENSSL_cpuid_setup + +.comm OPENSSL_s390xcap_P,8,8 diff --git a/crypto/sha/asm/sha1-s390x.pl b/crypto/sha/asm/sha1-s390x.pl index eb6f8dfc82..4b17848287 100644 --- a/crypto/sha/asm/sha1-s390x.pl +++ b/crypto/sha/asm/sha1-s390x.pl @@ -143,6 +143,10 @@ Ktable: .long 0x5a827999,0x6ed9eba1,0x8f1bbcdc,0xca62c1d6 sha1_block_data_order: ___ $code.=<<___ if ($kimdfunc); + larl %r1,OPENSSL_s390xcap_P + lg %r0,0(%r1) + tmhl %r0,0x4000 # check for message-security assist + jz .Lsoftware lghi %r0,0 la %r1,16($sp) .long 0xb93e0002 # kimd %r0,%r2 @@ -213,6 +217,7 @@ $code.=<<___; br %r14 .size sha1_block_data_order,.-sha1_block_data_order .string "SHA1 block transform for s390x, CRYPTOGAMS by " +.comm OPENSSL_s390xcap_P,8,8 ___ $code =~ s/\`([^\`]*)\`/eval $1/gem; diff --git a/crypto/sha/asm/sha512-s390x.pl b/crypto/sha/asm/sha512-s390x.pl index 5811d74d09..e7ef2d5a9f 100644 --- a/crypto/sha/asm/sha512-s390x.pl +++ b/crypto/sha/asm/sha512-s390x.pl @@ -214,6 +214,10 @@ $code.=<<___; $Func: ___ $code.=<<___ if ($kimdfunc); + larl %r1,OPENSSL_s390xcap_P + lg %r0,0(%r1) + tmhl %r0,0x4000 # check for message-security assist + jz .Lsoftware lghi %r0,0 la %r1,16($sp) .long 0xb93e0002 # kimd %r0,%r2 @@ -286,6 +290,7 @@ $code.=<<___; br %r14 .size $Func,.-$Func .string "SHA${label} block transform for s390x, CRYPTOGAMS by " +.comm OPENSSL_s390xcap_P,8,8 ___ $code =~ s/\`([^\`]*)\`/eval $1/gem; -- 2.34.1