File 0004-s390x-assembly-pack-add-OPENSSL_s390xcap-environment.patch of Package openssl-1_1.13606

From 3e1c11dd482dd4626989bb6d84fc708d9bb95219 Mon Sep 17 00:00:00 2001
From: Patrick Steuer <patrick.steuer@de.ibm.com>
Date: Mon, 30 Jan 2017 17:37:54 +0100
Subject: [PATCH 04/44] s390x assembly pack: add OPENSSL_s390xcap environment
 variable.

The OPENSSL_s390xcap environment variable is used to set bits in the s390x
capability vector to zero. This simplifies testing of different code paths.

Signed-off-by: Patrick Steuer <patrick.steuer@de.ibm.com>
---
 crypto/s390x_arch.h | 28 ++++++++++++++++++++++++++++
 crypto/s390xcap.c   | 33 +++++++++++++++++++++++++++++----
 2 files changed, 57 insertions(+), 4 deletions(-)
 create mode 100644 crypto/s390x_arch.h

Index: openssl-1.1.0g/crypto/s390x_arch.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ openssl-1.1.0g/crypto/s390x_arch.h	2018-01-10 15:26:40.291112320 +0100
@@ -0,0 +1,28 @@
+/*
+ * Copyright 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#ifndef S390X_ARCH_H
+# define S390X_ARCH_H
+
+# include <stdint.h>
+
+/*
+ * The elements of OPENSSL_s390xcap_P are the doublewords returned by the STFLE
+ * instruction followed by the doubleword pairs returned by instructions' QUERY
+ * functions. If STFLE returns fewer doublewords or an instruction is not
+ * supported, the corresponding element is zero. The order is as follows:
+ *
+ * STFLE:STFLE.KIMD:KIMD:KM:KM:KMC:KMC:KMCTR:KMCTR
+ */
+# define S390X_STFLE_DWORDS	2
+# define S390X_QUERY_DWORDS	8
+# define S390X_CAP_DWORDS	(S390X_STFLE_DWORDS + S390X_QUERY_DWORDS)
+extern unsigned long long OPENSSL_s390xcap_P[];
+
+#endif
Index: openssl-1.1.0g/crypto/s390xcap.c
===================================================================
--- openssl-1.1.0g.orig/crypto/s390xcap.c	2017-11-02 15:29:03.000000000 +0100
+++ openssl-1.1.0g/crypto/s390xcap.c	2018-01-10 15:27:42.988113439 +0100
@@ -14,6 +14,7 @@
 #include <signal.h>
 
 unsigned long long OPENSSL_s390xcap_P[10];
+#include "s390x_arch.h"
 
 static sigjmp_buf ill_jmp;
 static void ill_handler(int sig)
@@ -21,17 +22,21 @@ static void ill_handler(int sig)
     siglongjmp(ill_jmp, sig);
 }
 
-unsigned long OPENSSL_s390x_facilities(void);
+void OPENSSL_s390x_facilities(void);
 
 void OPENSSL_cpuid_setup(void)
 {
     sigset_t oset;
     struct sigaction ill_act, oact;
+    uint64_t vec;
+    char *env;
+    int off;
+    int i;
 
     if (OPENSSL_s390xcap_P[0])
         return;
 
-    OPENSSL_s390xcap_P[0] = 1UL << (8 * sizeof(unsigned long) - 1);
+    OPENSSL_s390xcap_P[0] = 1ULL << (8 * sizeof(uint64_t) - 1);
 
     memset(&ill_act, 0, sizeof(ill_act));
     ill_act.sa_handler = ill_handler;
@@ -47,4 +52,26 @@ void OPENSSL_cpuid_setup(void)
 
     sigaction(SIGILL, &oact, NULL);
     sigprocmask(SIG_SETMASK, &oset, NULL);
+
+    if ((env = getenv("OPENSSL_s390xcap")) != NULL) {
+        for (i = 0; i < S390X_CAP_DWORDS; i++) {
+            off = (env[0] == '~') ? 1 : 0;
+
+            if (sscanf(env + off, "%llx", (unsigned long long *)&vec) == 1)
+                OPENSSL_s390xcap_P[i] &= off ? ~vec : vec;
+
+            if (i == S390X_STFLE_DWORDS - 1)
+                env = strchr(env, '.');
+            else
+                env = strpbrk(env, ":.");
+
+            if (env == NULL)
+                break;
+
+            if (env[0] == '.')
+                i = S390X_STFLE_DWORDS - 1;
+
+            env++;
+        }
+    }
 }