Commit c8f37048 authored by Bernd Edlinger's avatar Bernd Edlinger
Browse files

PPC: Try out if mftb works before using it



If this fails try out if mfspr268 works.

Use OPENSSL_ppccap=0x20 for enabling mftb,
OPENSSL_ppccap=0x40 for enabling mfspr268,
and OPENSSL_ppccap=0 for enabling neither.

Fixes #8012

Reviewed-by: default avatarPaul Dale <paul.dale@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/8043)
parent 11642f35
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -460,4 +460,14 @@ uint32_t OPENSSL_rdtsc(void)
{
    return 0;
}

size_t OPENSSL_instrument_bus(unsigned int *out, size_t cnt)
{
    return 0;
}

size_t OPENSSL_instrument_bus2(unsigned int *out, size_t cnt, size_t max)
{
    return 0;
}
#endif
+2 −0
Original line number Diff line number Diff line
@@ -22,5 +22,7 @@ extern unsigned int OPENSSL_ppccap_P;
# define PPC_CRYPTO207   (1<<2)
# define PPC_FPU         (1<<3)
# define PPC_MADD300     (1<<4)
# define PPC_MFTB        (1<<5)
# define PPC_MFSPR268    (1<<6)

#endif
+51 −4
Original line number Diff line number Diff line
@@ -168,6 +168,45 @@ void OPENSSL_altivec_probe(void);
void OPENSSL_crypto207_probe(void);
void OPENSSL_madd300_probe(void);

long OPENSSL_rdtsc_mftb(void);
long OPENSSL_rdtsc_mfspr268(void);

uint32_t OPENSSL_rdtsc(void)
{
    if (OPENSSL_ppccap_P & PPC_MFTB)
        return OPENSSL_rdtsc_mftb();
    else if (OPENSSL_ppccap_P & PPC_MFSPR268)
        return OPENSSL_rdtsc_mfspr268();
    else
        return 0;
}

size_t OPENSSL_instrument_bus_mftb(unsigned int *, size_t);
size_t OPENSSL_instrument_bus_mfspr268(unsigned int *, size_t);

size_t OPENSSL_instrument_bus(unsigned int *out, size_t cnt)
{
    if (OPENSSL_ppccap_P & PPC_MFTB)
        return OPENSSL_instrument_bus_mftb(out, cnt);
    else if (OPENSSL_ppccap_P & PPC_MFSPR268)
        return OPENSSL_instrument_bus_mfspr268(out, cnt);
    else
        return 0;
}

size_t OPENSSL_instrument_bus2_mftb(unsigned int *, size_t, size_t);
size_t OPENSSL_instrument_bus2_mfspr268(unsigned int *, size_t, size_t);

size_t OPENSSL_instrument_bus2(unsigned int *out, size_t cnt, size_t max)
{
    if (OPENSSL_ppccap_P & PPC_MFTB)
        return OPENSSL_instrument_bus2_mftb(out, cnt, max);
    else if (OPENSSL_ppccap_P & PPC_MFSPR268)
        return OPENSSL_instrument_bus2_mfspr268(out, cnt, max);
    else
        return 0;
}

#if defined(__GLIBC__) && defined(__GLIBC_PREREQ)
# if __GLIBC_PREREQ(2, 16)
#  include <sys/auxv.h>
@@ -300,8 +339,6 @@ void OPENSSL_cpuid_setup(void)
        if (hwcap & HWCAP_ARCH_3_00) {
            OPENSSL_ppccap_P |= PPC_MADD300;
        }

        return;
    }
#endif

@@ -322,6 +359,7 @@ void OPENSSL_cpuid_setup(void)
    sigprocmask(SIG_SETMASK, &ill_act.sa_mask, &oset);
    sigaction(SIGILL, &ill_act, &ill_oact);

#ifndef OSSL_IMPLEMENT_GETAUXVAL
    if (sigsetjmp(ill_jmp,1) == 0) {
        OPENSSL_fpu_probe();
        OPENSSL_ppccap_P |= PPC_FPU;
@@ -355,6 +393,15 @@ void OPENSSL_cpuid_setup(void)
        OPENSSL_madd300_probe();
        OPENSSL_ppccap_P |= PPC_MADD300;
    }
#endif

    if (sigsetjmp(ill_jmp, 1) == 0) {
        OPENSSL_rdtsc_mftb();
        OPENSSL_ppccap_P |= PPC_MFTB;
    } else if (sigsetjmp(ill_jmp, 1) == 0) {
        OPENSSL_rdtsc_mfspr268();
        OPENSSL_ppccap_P |= PPC_MFSPR268;
    }

    sigaction(SIGILL, &ill_oact, NULL);
    sigprocmask(SIG_SETMASK, &oset, NULL);
+102 −21
Original line number Diff line number Diff line
@@ -124,26 +124,23 @@ Ladd: lwarx r5,0,r3
	.long	0
.size	.OPENSSL_atomic_add,.-.OPENSSL_atomic_add

.globl	.OPENSSL_rdtsc
.globl	.OPENSSL_rdtsc_mftb
.align	4
.OPENSSL_rdtsc:
___
$code.=<<___	if ($flavour =~ /64/);
	mftb	r3
___
$code.=<<___	if ($flavour !~ /64/);
Loop_rdtsc:
	mftbu	r5
.OPENSSL_rdtsc_mftb:
	mftb	r3
	mftbu	r4
	cmplw	r4,r5
	bne	Loop_rdtsc
___
$code.=<<___;
	blr
	.long	0
	.byte	0,12,0x14,0,0,0,0,0
.size	.OPENSSL_rdtsc,.-.OPENSSL_rdtsc
.size	.OPENSSL_rdtsc_mftb,.-.OPENSSL_rdtsc_mftb

.globl	.OPENSSL_rdtsc_mfspr268
.align	4
.OPENSSL_rdtsc_mfspr268:
	mfspr	r3,268
	blr
	.long	0
	.byte	0,12,0x14,0,0,0,0,0
.size	.OPENSSL_rdtsc_mfspr268,.-.OPENSSL_rdtsc_mfspr268

.globl	.OPENSSL_cleanse
.align	4
@@ -210,9 +207,9 @@ my ($tick,$lasttick)=("r6","r7");
my ($diff,$lastdiff)=("r8","r9");

$code.=<<___;
.globl	.OPENSSL_instrument_bus
.globl	.OPENSSL_instrument_bus_mftb
.align	4
.OPENSSL_instrument_bus:
.OPENSSL_instrument_bus_mftb:
	mtctr	$cnt

	mftb	$lasttick		# collect 1st tick
@@ -240,11 +237,11 @@ Loop: mftb $tick
	.long	0
	.byte	0,12,0x14,0,0,0,2,0
	.long	0
.size	.OPENSSL_instrument_bus,.-.OPENSSL_instrument_bus
.size	.OPENSSL_instrument_bus_mftb,.-.OPENSSL_instrument_bus_mftb

.globl	.OPENSSL_instrument_bus2
.globl	.OPENSSL_instrument_bus2_mftb
.align	4
.OPENSSL_instrument_bus2:
.OPENSSL_instrument_bus2_mftb:
	mr	r0,$cnt
	slwi	$cnt,$cnt,2

@@ -292,7 +289,91 @@ Ldone2:
	.long	0
	.byte	0,12,0x14,0,0,0,3,0
	.long	0
.size	.OPENSSL_instrument_bus2,.-.OPENSSL_instrument_bus2
.size	.OPENSSL_instrument_bus2_mftb,.-.OPENSSL_instrument_bus2_mftb

.globl	.OPENSSL_instrument_bus_mfspr268
.align	4
.OPENSSL_instrument_bus_mfspr268:
	mtctr	$cnt

	mfspr	$lasttick,268		# collect 1st tick
	li	$diff,0

	dcbf	0,$out			# flush cache line
	lwarx	$tick,0,$out		# load and lock
	add	$tick,$tick,$diff
	stwcx.	$tick,0,$out
	stwx	$tick,0,$out

Loop3:	mfspr	$tick,268
	sub	$diff,$tick,$lasttick
	mr	$lasttick,$tick
	dcbf	0,$out			# flush cache line
	lwarx	$tick,0,$out		# load and lock
	add	$tick,$tick,$diff
	stwcx.	$tick,0,$out
	stwx	$tick,0,$out
	addi	$out,$out,4		# ++$out
	bdnz	Loop3

	mr	r3,$cnt
	blr
	.long	0
	.byte	0,12,0x14,0,0,0,2,0
	.long	0
.size	.OPENSSL_instrument_bus_mfspr268,.-.OPENSSL_instrument_bus_mfspr268

.globl	.OPENSSL_instrument_bus2_mfspr268
.align	4
.OPENSSL_instrument_bus2_mfspr268:
	mr	r0,$cnt
	slwi	$cnt,$cnt,2

	mfspr	$lasttick,268		# collect 1st tick
	li	$diff,0

	dcbf	0,$out			# flush cache line
	lwarx	$tick,0,$out		# load and lock
	add	$tick,$tick,$diff
	stwcx.	$tick,0,$out
	stwx	$tick,0,$out

	mfspr	$tick,268		# collect 1st diff
	sub	$diff,$tick,$lasttick
	mr	$lasttick,$tick
	mr	$lastdiff,$diff
Loop4:
	dcbf	0,$out			# flush cache line
	lwarx	$tick,0,$out		# load and lock
	add	$tick,$tick,$diff
	stwcx.	$tick,0,$out
	stwx	$tick,0,$out

	addic.	$max,$max,-1
	beq	Ldone4

	mfspr	$tick,268
	sub	$diff,$tick,$lasttick
	mr	$lasttick,$tick
	cmplw	7,$diff,$lastdiff
	mr	$lastdiff,$diff

	mfcr	$tick			# pull cr
	not	$tick,$tick		# flip bits
	rlwinm	$tick,$tick,1,29,29	# isolate flipped eq bit and scale

	sub.	$cnt,$cnt,$tick		# conditional --$cnt
	add	$out,$out,$tick		# conditional ++$out
	bne	Loop4

Ldone4:
	srwi	$cnt,$cnt,2
	sub	r3,r0,$cnt
	blr
	.long	0
	.byte	0,12,0x14,0,0,0,3,0
	.long	0
.size	.OPENSSL_instrument_bus2_mfspr268,.-.OPENSSL_instrument_bus2_mfspr268
___
}

+2 −0
Original line number Diff line number Diff line
@@ -92,5 +92,7 @@ void *openssl_fopen(const char *filename, const char *mode);
# endif

uint32_t OPENSSL_rdtsc(void);
size_t OPENSSL_instrument_bus(unsigned int *, size_t);
size_t OPENSSL_instrument_bus2(unsigned int *, size_t, size_t);

#endif