summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authormiod <>2014-05-03 11:39:46 +0000
committermiod <>2014-05-03 11:39:46 +0000
commite6f8192f5af2a5d7ccc7c33d9e1e7a057a09cc89 (patch)
tree4894a238b9d6f90afcd5e05c9289f12898608e8f /src/lib
parent3b20898d344ff6a38978c4f7510cf37c20ab0986 (diff)
downloadopenbsd-e6f8192f5af2a5d7ccc7c33d9e1e7a057a09cc89.tar.gz
openbsd-e6f8192f5af2a5d7ccc7c33d9e1e7a057a09cc89.tar.bz2
openbsd-e6f8192f5af2a5d7ccc7c33d9e1e7a057a09cc89.zip
Detect Altivec support with the machdep.altivec sysctl rather than setmp and
a SIGILL handler. Do not attempt to detect and use a 64-bit FPU yet.
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/libcrypto/ppccap.c112
-rwxr-xr-xsrc/lib/libcrypto/ppccpuid.pl10
-rw-r--r--src/lib/libssl/src/crypto/ppccap.c112
-rwxr-xr-xsrc/lib/libssl/src/crypto/ppccpuid.pl10
4 files changed, 40 insertions, 204 deletions
diff --git a/src/lib/libcrypto/ppccap.c b/src/lib/libcrypto/ppccap.c
index 4d7dd38dd1..4cedefed2c 100644
--- a/src/lib/libcrypto/ppccap.c
+++ b/src/lib/libcrypto/ppccap.c
@@ -1,124 +1,48 @@
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <setjmp.h>
5#include <signal.h>
6#include <unistd.h> 1#include <unistd.h>
2#include <sys/param.h>
3#include <sys/sysctl.h>
4#include <machine/cpu.h>
5
7#include <crypto.h> 6#include <crypto.h>
8#include <openssl/bn.h> 7#include <openssl/bn.h>
9 8
9#ifdef unused
10#define PPC_FPU64 (1<<0) 10#define PPC_FPU64 (1<<0)
11#define PPC_ALTIVEC (1<<1) 11#define PPC_ALTIVEC (1<<1)
12 12
13static int OPENSSL_ppccap_P = 0; 13static int OPENSSL_ppccap_P = 0;
14 14#endif
15static sigset_t all_masked;
16 15
17#ifdef OPENSSL_BN_ASM_MONT 16#ifdef OPENSSL_BN_ASM_MONT
17extern int bn_mul_mont_int(BN_ULONG *, const BN_ULONG *, const BN_ULONG *,
18 const BN_ULONG *, const BN_ULONG *, int);
18int 19int
19bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, 20bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
20 const BN_ULONG *np, const BN_ULONG *n0, int num) 21 const BN_ULONG *np, const BN_ULONG *n0, int num)
21{ 22{
22 int bn_mul_mont_fpu64(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np, const BN_ULONG *n0, int num);
23 int bn_mul_mont_int(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np, const BN_ULONG *n0, int num);
24
25 if (sizeof(size_t) == 4) {
26#if (defined(__APPLE__) && defined(__MACH__))
27 if (num >= 8 && (num&3) == 0 && (OPENSSL_ppccap_P&PPC_FPU64))
28 return bn_mul_mont_fpu64(rp, ap, bp, np, n0, num);
29#else
30 /* boundary of 32 was experimentally determined on
31 Linux 2.6.22, might have to be adjusted on AIX... */
32 if (num >= 32 && (num&3) == 0 && (OPENSSL_ppccap_P&PPC_FPU64)) {
33 sigset_t oset;
34 int ret;
35
36 sigprocmask(SIG_SETMASK, &all_masked, &oset);
37 ret = bn_mul_mont_fpu64(rp, ap, bp, np, n0, num);
38 sigprocmask(SIG_SETMASK, &oset, NULL);
39
40 return ret;
41 }
42#endif
43 } else if ((OPENSSL_ppccap_P&PPC_FPU64))
44 /* this is a "must" on POWER6, but run-time detection
45 * is not implemented yet... */
46 return bn_mul_mont_fpu64(rp, ap, bp, np, n0, num);
47
48 return bn_mul_mont_int(rp, ap, bp, np, n0, num); 23 return bn_mul_mont_int(rp, ap, bp, np, n0, num);
49} 24}
50#endif 25#endif
51 26
52static sigjmp_buf ill_jmp; 27#ifdef unused
53static void ill_handler (int sig) 28void OPENSSL_cpuid_setup(void) __attribute__((constructor));
54{
55 siglongjmp(ill_jmp, sig);
56}
57
58void OPENSSL_ppc64_probe(void);
59void OPENSSL_altivec_probe(void);
60 29
61void 30void
62OPENSSL_cpuid_setup(void) 31OPENSSL_cpuid_setup(void)
63{ 32{
64 char *e; 33 static const int mib[2] = { CTL_MACHDEP, CPU_ALTIVEC };
65 struct sigaction ill_oact, ill_act;
66 sigset_t oset;
67 static int trigger = 0; 34 static int trigger = 0;
35 int altivec = 0;
36 size_t size;
68 37
69 if (trigger) 38 if (trigger)
70 return; 39 return;
71 trigger = 1; 40 trigger = 1;
72 41
73 sigfillset(&all_masked); 42 size = sizeof altivec;
74 sigdelset(&all_masked, SIGILL); 43 if (sysctl(mib, 2, &altivec, &size, NULL, 0) != -1) {
75 sigdelset(&all_masked, SIGTRAP); 44 if (altivec != 0)
76#ifdef SIGEMT 45 OPENSSL_ppccap_P |= PPC_ALTIVEC;
77 sigdelset(&all_masked, SIGEMT);
78#endif
79 sigdelset(&all_masked, SIGFPE);
80 sigdelset(&all_masked, SIGBUS);
81 sigdelset(&all_masked, SIGSEGV);
82
83 if ((e = getenv("OPENSSL_ppccap"))) {
84 OPENSSL_ppccap_P = strtoul(e, NULL, 0);
85 return;
86 }
87
88 OPENSSL_ppccap_P = 0;
89
90#if defined(_AIX)
91 if (sizeof(size_t) == 4
92# if defined(_SC_AIX_KERNEL_BITMODE)
93 && sysconf(_SC_AIX_KERNEL_BITMODE) != 64
94# endif
95 )
96 return;
97#endif
98
99 memset(&ill_act, 0, sizeof(ill_act));
100 ill_act.sa_handler = ill_handler;
101 ill_act.sa_mask = all_masked;
102
103 sigprocmask(SIG_SETMASK, &ill_act.sa_mask, &oset);
104 sigaction(SIGILL, &ill_act, &ill_oact);
105
106 if (sizeof(size_t) == 4) {
107 if (sigsetjmp(ill_jmp, 1) == 0) {
108 OPENSSL_ppc64_probe();
109 OPENSSL_ppccap_P |= PPC_FPU64;
110 }
111 } else {
112 /*
113 * Wanted code detecting POWER6 CPU and setting PPC_FPU64
114 */
115 }
116
117 if (sigsetjmp(ill_jmp, 1) == 0) {
118 OPENSSL_altivec_probe();
119 OPENSSL_ppccap_P |= PPC_ALTIVEC;
120 } 46 }
121
122 sigaction (SIGILL, &ill_oact, NULL);
123 sigprocmask(SIG_SETMASK, &oset, NULL);
124} 47}
48#endif
diff --git a/src/lib/libcrypto/ppccpuid.pl b/src/lib/libcrypto/ppccpuid.pl
index 37c33c051a..0cef7014b6 100755
--- a/src/lib/libcrypto/ppccpuid.pl
+++ b/src/lib/libcrypto/ppccpuid.pl
@@ -23,6 +23,7 @@ $code=<<___;
23.machine "any" 23.machine "any"
24.text 24.text
25 25
26#if 0
26.globl .OPENSSL_ppc64_probe 27.globl .OPENSSL_ppc64_probe
27.align 4 28.align 4
28.OPENSSL_ppc64_probe: 29.OPENSSL_ppc64_probe:
@@ -31,14 +32,7 @@ $code=<<___;
31 blr 32 blr
32 .long 0 33 .long 0
33 .byte 0,12,0x14,0,0,0,0,0 34 .byte 0,12,0x14,0,0,0,0,0
34 35#endif
35.globl .OPENSSL_altivec_probe
36.align 4
37.OPENSSL_altivec_probe:
38 .long 0x10000484 # vor v0,v0,v0
39 blr
40 .long 0
41 .byte 0,12,0x14,0,0,0,0,0
42 36
43.globl .OPENSSL_wipe_cpu 37.globl .OPENSSL_wipe_cpu
44.align 4 38.align 4
diff --git a/src/lib/libssl/src/crypto/ppccap.c b/src/lib/libssl/src/crypto/ppccap.c
index 4d7dd38dd1..4cedefed2c 100644
--- a/src/lib/libssl/src/crypto/ppccap.c
+++ b/src/lib/libssl/src/crypto/ppccap.c
@@ -1,124 +1,48 @@
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <setjmp.h>
5#include <signal.h>
6#include <unistd.h> 1#include <unistd.h>
2#include <sys/param.h>
3#include <sys/sysctl.h>
4#include <machine/cpu.h>
5
7#include <crypto.h> 6#include <crypto.h>
8#include <openssl/bn.h> 7#include <openssl/bn.h>
9 8
9#ifdef unused
10#define PPC_FPU64 (1<<0) 10#define PPC_FPU64 (1<<0)
11#define PPC_ALTIVEC (1<<1) 11#define PPC_ALTIVEC (1<<1)
12 12
13static int OPENSSL_ppccap_P = 0; 13static int OPENSSL_ppccap_P = 0;
14 14#endif
15static sigset_t all_masked;
16 15
17#ifdef OPENSSL_BN_ASM_MONT 16#ifdef OPENSSL_BN_ASM_MONT
17extern int bn_mul_mont_int(BN_ULONG *, const BN_ULONG *, const BN_ULONG *,
18 const BN_ULONG *, const BN_ULONG *, int);
18int 19int
19bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, 20bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
20 const BN_ULONG *np, const BN_ULONG *n0, int num) 21 const BN_ULONG *np, const BN_ULONG *n0, int num)
21{ 22{
22 int bn_mul_mont_fpu64(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np, const BN_ULONG *n0, int num);
23 int bn_mul_mont_int(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np, const BN_ULONG *n0, int num);
24
25 if (sizeof(size_t) == 4) {
26#if (defined(__APPLE__) && defined(__MACH__))
27 if (num >= 8 && (num&3) == 0 && (OPENSSL_ppccap_P&PPC_FPU64))
28 return bn_mul_mont_fpu64(rp, ap, bp, np, n0, num);
29#else
30 /* boundary of 32 was experimentally determined on
31 Linux 2.6.22, might have to be adjusted on AIX... */
32 if (num >= 32 && (num&3) == 0 && (OPENSSL_ppccap_P&PPC_FPU64)) {
33 sigset_t oset;
34 int ret;
35
36 sigprocmask(SIG_SETMASK, &all_masked, &oset);
37 ret = bn_mul_mont_fpu64(rp, ap, bp, np, n0, num);
38 sigprocmask(SIG_SETMASK, &oset, NULL);
39
40 return ret;
41 }
42#endif
43 } else if ((OPENSSL_ppccap_P&PPC_FPU64))
44 /* this is a "must" on POWER6, but run-time detection
45 * is not implemented yet... */
46 return bn_mul_mont_fpu64(rp, ap, bp, np, n0, num);
47
48 return bn_mul_mont_int(rp, ap, bp, np, n0, num); 23 return bn_mul_mont_int(rp, ap, bp, np, n0, num);
49} 24}
50#endif 25#endif
51 26
52static sigjmp_buf ill_jmp; 27#ifdef unused
53static void ill_handler (int sig) 28void OPENSSL_cpuid_setup(void) __attribute__((constructor));
54{
55 siglongjmp(ill_jmp, sig);
56}
57
58void OPENSSL_ppc64_probe(void);
59void OPENSSL_altivec_probe(void);
60 29
61void 30void
62OPENSSL_cpuid_setup(void) 31OPENSSL_cpuid_setup(void)
63{ 32{
64 char *e; 33 static const int mib[2] = { CTL_MACHDEP, CPU_ALTIVEC };
65 struct sigaction ill_oact, ill_act;
66 sigset_t oset;
67 static int trigger = 0; 34 static int trigger = 0;
35 int altivec = 0;
36 size_t size;
68 37
69 if (trigger) 38 if (trigger)
70 return; 39 return;
71 trigger = 1; 40 trigger = 1;
72 41
73 sigfillset(&all_masked); 42 size = sizeof altivec;
74 sigdelset(&all_masked, SIGILL); 43 if (sysctl(mib, 2, &altivec, &size, NULL, 0) != -1) {
75 sigdelset(&all_masked, SIGTRAP); 44 if (altivec != 0)
76#ifdef SIGEMT 45 OPENSSL_ppccap_P |= PPC_ALTIVEC;
77 sigdelset(&all_masked, SIGEMT);
78#endif
79 sigdelset(&all_masked, SIGFPE);
80 sigdelset(&all_masked, SIGBUS);
81 sigdelset(&all_masked, SIGSEGV);
82
83 if ((e = getenv("OPENSSL_ppccap"))) {
84 OPENSSL_ppccap_P = strtoul(e, NULL, 0);
85 return;
86 }
87
88 OPENSSL_ppccap_P = 0;
89
90#if defined(_AIX)
91 if (sizeof(size_t) == 4
92# if defined(_SC_AIX_KERNEL_BITMODE)
93 && sysconf(_SC_AIX_KERNEL_BITMODE) != 64
94# endif
95 )
96 return;
97#endif
98
99 memset(&ill_act, 0, sizeof(ill_act));
100 ill_act.sa_handler = ill_handler;
101 ill_act.sa_mask = all_masked;
102
103 sigprocmask(SIG_SETMASK, &ill_act.sa_mask, &oset);
104 sigaction(SIGILL, &ill_act, &ill_oact);
105
106 if (sizeof(size_t) == 4) {
107 if (sigsetjmp(ill_jmp, 1) == 0) {
108 OPENSSL_ppc64_probe();
109 OPENSSL_ppccap_P |= PPC_FPU64;
110 }
111 } else {
112 /*
113 * Wanted code detecting POWER6 CPU and setting PPC_FPU64
114 */
115 }
116
117 if (sigsetjmp(ill_jmp, 1) == 0) {
118 OPENSSL_altivec_probe();
119 OPENSSL_ppccap_P |= PPC_ALTIVEC;
120 } 46 }
121
122 sigaction (SIGILL, &ill_oact, NULL);
123 sigprocmask(SIG_SETMASK, &oset, NULL);
124} 47}
48#endif
diff --git a/src/lib/libssl/src/crypto/ppccpuid.pl b/src/lib/libssl/src/crypto/ppccpuid.pl
index 37c33c051a..0cef7014b6 100755
--- a/src/lib/libssl/src/crypto/ppccpuid.pl
+++ b/src/lib/libssl/src/crypto/ppccpuid.pl
@@ -23,6 +23,7 @@ $code=<<___;
23.machine "any" 23.machine "any"
24.text 24.text
25 25
26#if 0
26.globl .OPENSSL_ppc64_probe 27.globl .OPENSSL_ppc64_probe
27.align 4 28.align 4
28.OPENSSL_ppc64_probe: 29.OPENSSL_ppc64_probe:
@@ -31,14 +32,7 @@ $code=<<___;
31 blr 32 blr
32 .long 0 33 .long 0
33 .byte 0,12,0x14,0,0,0,0,0 34 .byte 0,12,0x14,0,0,0,0,0
34 35#endif
35.globl .OPENSSL_altivec_probe
36.align 4
37.OPENSSL_altivec_probe:
38 .long 0x10000484 # vor v0,v0,v0
39 blr
40 .long 0
41 .byte 0,12,0x14,0,0,0,0,0
42 36
43.globl .OPENSSL_wipe_cpu 37.globl .OPENSSL_wipe_cpu
44.align 4 38.align 4