summaryrefslogtreecommitdiffstats
path: root/crypto/s390xcap.c
diff options
context:
space:
mode:
authorPatrick Steuer <patrick.steuer@de.ibm.com>2017-10-02 11:24:02 +0200
committerAndy Polyakov <appro@openssl.org>2017-10-30 14:31:32 +0100
commitbc4e831ccd81a1d22a7462df645c884ce33ea7c0 (patch)
tree3ee3ba6299281803d00c0650b43db0fa5991397b /crypto/s390xcap.c
parent7a908204ed3afe1379151c6d090148edb2fcc87e (diff)
s390x assembly pack: extend s390x capability vector.
Extend the s390x capability vector to store the longer facility list available from z13 onwards. The bits indicating the vector extensions are set to zero, if the kernel does not enable the vector facility. Also add capability bits returned by the crypto instructions' query functions. Signed-off-by: Patrick Steuer <patrick.steuer@de.ibm.com> Reviewed-by: Andy Polyakov <appro@openssl.org> Reviewed-by: Tim Hudson <tjh@openssl.org> (Merged from https://github.com/openssl/openssl/pull/4542)
Diffstat (limited to 'crypto/s390xcap.c')
-rw-r--r--crypto/s390xcap.c28
1 files changed, 22 insertions, 6 deletions
diff --git a/crypto/s390xcap.c b/crypto/s390xcap.c
index 93c5327ffb..e7c7f0a357 100644
--- a/crypto/s390xcap.c
+++ b/crypto/s390xcap.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2016 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2010-2017 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@@ -13,8 +13,7 @@
#include <setjmp.h>
#include <signal.h>
#include "internal/cryptlib.h"
-
-extern unsigned long OPENSSL_s390xcap_P[];
+#include "s390x_arch.h"
static sigjmp_buf ill_jmp;
static void ill_handler(int sig)
@@ -22,30 +21,47 @@ static void ill_handler(int sig)
siglongjmp(ill_jmp, sig);
}
-unsigned long OPENSSL_s390x_facilities(void);
+void OPENSSL_s390x_facilities(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;
- if (OPENSSL_s390xcap_P[0])
+ if (OPENSSL_s390xcap_P.stfle[0])
return;
- OPENSSL_s390xcap_P[0] = 1UL << (8 * sizeof(unsigned long) - 1);
+ /* set a bit that will not be tested later */
+ OPENSSL_s390xcap_P.stfle[0] |= S390X_CAPBIT(0);
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);
+ sigaction(SIGFPE, &ill_act, &oact);
/* 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, NULL);
sigaction(SIGILL, &oact, NULL);
sigprocmask(SIG_SETMASK, &oset, NULL);
}