diff options
author | miod <> | 2014-05-03 11:39:46 +0000 |
---|---|---|
committer | miod <> | 2014-05-03 11:39:46 +0000 |
commit | e6f8192f5af2a5d7ccc7c33d9e1e7a057a09cc89 (patch) | |
tree | 4894a238b9d6f90afcd5e05c9289f12898608e8f /src/lib | |
parent | 3b20898d344ff6a38978c4f7510cf37c20ab0986 (diff) | |
download | openbsd-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.c | 112 | ||||
-rwxr-xr-x | src/lib/libcrypto/ppccpuid.pl | 10 | ||||
-rw-r--r-- | src/lib/libssl/src/crypto/ppccap.c | 112 | ||||
-rwxr-xr-x | src/lib/libssl/src/crypto/ppccpuid.pl | 10 |
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 | ||
13 | static int OPENSSL_ppccap_P = 0; | 13 | static int OPENSSL_ppccap_P = 0; |
14 | 14 | #endif | |
15 | static sigset_t all_masked; | ||
16 | 15 | ||
17 | #ifdef OPENSSL_BN_ASM_MONT | 16 | #ifdef OPENSSL_BN_ASM_MONT |
17 | extern int bn_mul_mont_int(BN_ULONG *, const BN_ULONG *, const BN_ULONG *, | ||
18 | const BN_ULONG *, const BN_ULONG *, int); | ||
18 | int | 19 | int |
19 | bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, | 20 | bn_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 | ||
52 | static sigjmp_buf ill_jmp; | 27 | #ifdef unused |
53 | static void ill_handler (int sig) | 28 | void OPENSSL_cpuid_setup(void) __attribute__((constructor)); |
54 | { | ||
55 | siglongjmp(ill_jmp, sig); | ||
56 | } | ||
57 | |||
58 | void OPENSSL_ppc64_probe(void); | ||
59 | void OPENSSL_altivec_probe(void); | ||
60 | 29 | ||
61 | void | 30 | void |
62 | OPENSSL_cpuid_setup(void) | 31 | OPENSSL_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 | ||
13 | static int OPENSSL_ppccap_P = 0; | 13 | static int OPENSSL_ppccap_P = 0; |
14 | 14 | #endif | |
15 | static sigset_t all_masked; | ||
16 | 15 | ||
17 | #ifdef OPENSSL_BN_ASM_MONT | 16 | #ifdef OPENSSL_BN_ASM_MONT |
17 | extern int bn_mul_mont_int(BN_ULONG *, const BN_ULONG *, const BN_ULONG *, | ||
18 | const BN_ULONG *, const BN_ULONG *, int); | ||
18 | int | 19 | int |
19 | bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, | 20 | bn_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 | ||
52 | static sigjmp_buf ill_jmp; | 27 | #ifdef unused |
53 | static void ill_handler (int sig) | 28 | void OPENSSL_cpuid_setup(void) __attribute__((constructor)); |
54 | { | ||
55 | siglongjmp(ill_jmp, sig); | ||
56 | } | ||
57 | |||
58 | void OPENSSL_ppc64_probe(void); | ||
59 | void OPENSSL_altivec_probe(void); | ||
60 | 29 | ||
61 | void | 30 | void |
62 | OPENSSL_cpuid_setup(void) | 31 | OPENSSL_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 |