[PATCH v4 1/9] selftests/powerpc: Test the preservation of FPU and VMX regs across syscall
Naveen N. Rao
naveen.n.rao at linux.vnet.ibm.com
Tue Feb 16 03:59:17 AEDT 2016
On 2016/02/15 04:07PM, Cyril Bur wrote:
> Test that the non volatile floating point and Altivec registers get
> correctly preserved across the fork() syscall.
>
> fork() works nicely for this purpose, the registers should be the same for
> both parent and child
>
> Signed-off-by: Cyril Bur <cyrilbur at gmail.com>
> ---
> tools/testing/selftests/powerpc/Makefile | 3 +-
> tools/testing/selftests/powerpc/basic_asm.h | 30 ++++
> tools/testing/selftests/powerpc/math/.gitignore | 2 +
> tools/testing/selftests/powerpc/math/Makefile | 14 ++
> tools/testing/selftests/powerpc/math/fpu_asm.S | 161 +++++++++++++++++
> tools/testing/selftests/powerpc/math/fpu_syscall.c | 90 ++++++++++
> tools/testing/selftests/powerpc/math/vmx_asm.S | 193 +++++++++++++++++++++
> tools/testing/selftests/powerpc/math/vmx_syscall.c | 92 ++++++++++
> 8 files changed, 584 insertions(+), 1 deletion(-)
> create mode 100644 tools/testing/selftests/powerpc/basic_asm.h
> create mode 100644 tools/testing/selftests/powerpc/math/.gitignore
> create mode 100644 tools/testing/selftests/powerpc/math/Makefile
> create mode 100644 tools/testing/selftests/powerpc/math/fpu_asm.S
> create mode 100644 tools/testing/selftests/powerpc/math/fpu_syscall.c
> create mode 100644 tools/testing/selftests/powerpc/math/vmx_asm.S
> create mode 100644 tools/testing/selftests/powerpc/math/vmx_syscall.c
>
> diff --git a/tools/testing/selftests/powerpc/Makefile b/tools/testing/selftests/powerpc/Makefile
> index 0c2706b..19e8191 100644
> --- a/tools/testing/selftests/powerpc/Makefile
> +++ b/tools/testing/selftests/powerpc/Makefile
> @@ -22,7 +22,8 @@ SUB_DIRS = benchmarks \
> switch_endian \
> syscalls \
> tm \
> - vphn
> + vphn \
> + math
>
> endif
>
> diff --git a/tools/testing/selftests/powerpc/basic_asm.h b/tools/testing/selftests/powerpc/basic_asm.h
> new file mode 100644
> index 0000000..f243da0
> --- /dev/null
> +++ b/tools/testing/selftests/powerpc/basic_asm.h
> @@ -0,0 +1,30 @@
> +#include <ppc-asm.h>
> +#include <asm/unistd.h>
> +
> +#define LOAD_REG_IMMEDIATE(reg,expr) \
> + lis reg,(expr)@highest; \
> + ori reg,reg,(expr)@higher; \
> + rldicr reg,reg,32,31; \
> + oris reg,reg,(expr)@high; \
> + ori reg,reg,(expr)@l;
> +
> +/* It is very important to note here that _extra is the extra amount of
> + * stack space needed.
> + * This space must be accessed at sp + 32!
This looks to be specific to ABIv2. Is this series limited to ppc64le?
If so, you might want to ensure this only builds there.
Also:
#define PPC_ABIV2_MIN_STACK_SIZE 32
or just:
#define PPC_MIN_STACK 32
... is helpful. And, you might want to base the rest of your code that
use PUSH_BASIC_STACK() on that. If we ever want to have these tests run
anywhere else, that'll help a lot. (See further below)
> + */
> +#define PUSH_BASIC_STACK(_extra) \
> + mflr r0; \
> + std r0,16(sp); \
> + stdu sp,-(_extra + 32)(sp); \
> + mfcr r0; \
> + stw r0,8(sp); \
> + std 2,24(sp);
^^
Better to use r2 here and below.
> +
> +#define POP_BASIC_STACK(_extra) \
> + ld 2,24(sp); \
> + lwz r0,8(sp); \
> + mtcr r0; \
> + addi sp,sp,(_extra + 32); \
> + ld r0,16(sp); \
> + mtlr r0;
> +
> diff --git a/tools/testing/selftests/powerpc/math/.gitignore b/tools/testing/selftests/powerpc/math/.gitignore
> new file mode 100644
> index 0000000..b19b269
> --- /dev/null
> +++ b/tools/testing/selftests/powerpc/math/.gitignore
> @@ -0,0 +1,2 @@
> +fpu_syscall
> +vmx_syscall
> diff --git a/tools/testing/selftests/powerpc/math/Makefile b/tools/testing/selftests/powerpc/math/Makefile
> new file mode 100644
> index 0000000..418bef1
> --- /dev/null
> +++ b/tools/testing/selftests/powerpc/math/Makefile
> @@ -0,0 +1,14 @@
> +TEST_PROGS := fpu_syscall vmx_syscall
> +
> +all: $(TEST_PROGS)
> +
> +$(TEST_PROGS): ../harness.c
> +$(TEST_PROGS): CFLAGS += -O2 -g -pthread -m64 -maltivec
> +
> +fpu_syscall: fpu_asm.S
> +vmx_syscall: vmx_asm.S
> +
> +include ../../lib.mk
> +
> +clean:
> + rm -f $(TEST_PROGS) *.o
> diff --git a/tools/testing/selftests/powerpc/math/fpu_asm.S b/tools/testing/selftests/powerpc/math/fpu_asm.S
> new file mode 100644
> index 0000000..8733874
> --- /dev/null
> +++ b/tools/testing/selftests/powerpc/math/fpu_asm.S
> @@ -0,0 +1,161 @@
> +/*
> + * Copyright 2015, Cyril Bur, IBM Corp.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version
> + * 2 of the License, or (at your option) any later version.
> + */
> +
> +#include "../basic_asm.h"
> +
> +#define PUSH_FPU(pos) \
> + stfd f14,pos(sp); \
> + stfd f15,pos+8(sp); \
> + stfd f16,pos+16(sp); \
> + stfd f17,pos+24(sp); \
> + stfd f18,pos+32(sp); \
> + stfd f19,pos+40(sp); \
> + stfd f20,pos+48(sp); \
> + stfd f21,pos+56(sp); \
> + stfd f22,pos+64(sp); \
> + stfd f23,pos+72(sp); \
> + stfd f24,pos+80(sp); \
> + stfd f25,pos+88(sp); \
> + stfd f26,pos+96(sp); \
> + stfd f27,pos+104(sp); \
> + stfd f28,pos+112(sp); \
> + stfd f29,pos+120(sp); \
> + stfd f30,pos+128(sp); \
> + stfd f31,pos+136(sp);
> +
> +#define POP_FPU(pos) \
> + lfd f14,pos(sp); \
> + lfd f15,pos+8(sp); \
> + lfd f16,pos+16(sp); \
> + lfd f17,pos+24(sp); \
> + lfd f18,pos+32(sp); \
> + lfd f19,pos+40(sp); \
> + lfd f20,pos+48(sp); \
> + lfd f21,pos+56(sp); \
> + lfd f22,pos+64(sp); \
> + lfd f23,pos+72(sp); \
> + lfd f24,pos+80(sp); \
> + lfd f25,pos+88(sp); \
> + lfd f26,pos+96(sp); \
> + lfd f27,pos+104(sp); \
> + lfd f28,pos+112(sp); \
> + lfd f29,pos+120(sp); \
> + lfd f30,pos+128(sp); \
> + lfd f31,pos+136(sp);
> +
> +#Careful calling this, it will 'clobber' fpu (by design)
> +#Don't call this from C
> +FUNC_START(load_fpu)
> + lfd f14,0(r3)
> + lfd f15,8(r3)
> + lfd f16,16(r3)
> + lfd f17,24(r3)
> + lfd f18,32(r3)
> + lfd f19,40(r3)
> + lfd f20,48(r3)
> + lfd f21,56(r3)
> + lfd f22,64(r3)
> + lfd f23,72(r3)
> + lfd f24,80(r3)
> + lfd f25,88(r3)
> + lfd f26,96(r3)
> + lfd f27,104(r3)
> + lfd f28,112(r3)
> + lfd f29,120(r3)
> + lfd f30,128(r3)
> + lfd f31,136(r3)
> + blr
> +FUNC_END(load_fpu)
> +
> +FUNC_START(check_fpu)
> + mr r4,r3
> + li r3,1 #assume a bad result
> + lfd f0,0(r4)
> + fcmpu cr1,f0,f14
> + bne cr1,1f
> + lfd f0,8(r4)
> + fcmpu cr1,f0,f15
> + bne cr1,1f
> + lfd f0,16(r4)
> + fcmpu cr1,f0,f16
> + bne cr1,1f
> + lfd f0,24(r4)
> + fcmpu cr1,f0,f17
> + bne cr1,1f
> + lfd f0,32(r4)
> + fcmpu cr1,f0,f18
> + bne cr1,1f
> + lfd f0,40(r4)
> + fcmpu cr1,f0,f19
> + bne cr1,1f
> + lfd f0,48(r4)
> + fcmpu cr1,f0,f20
> + bne cr1,1f
> + lfd f0,56(r4)
> + fcmpu cr1,f0,f21
> + bne cr1,1f
> + lfd f0,64(r4)
> + fcmpu cr1,f0,f22
> + bne cr1,1f
> + lfd f0,72(r4)
> + fcmpu cr1,f0,f23
> + bne cr1,1f
> + lfd f0,80(r4)
> + fcmpu cr1,f0,f24
> + bne cr1,1f
> + lfd f0,88(r4)
> + fcmpu cr1,f0,f25
> + bne cr1,1f
> + lfd f0,96(r4)
> + fcmpu cr1,f0,f26
> + bne cr1,1f
> + lfd f0,104(r4)
> + fcmpu cr1,f0,f27
> + bne cr1,1f
> + lfd f0,112(r4)
> + fcmpu cr1,f0,f28
> + bne cr1,1f
> + lfd f0,120(r4)
> + fcmpu cr1,f0,f29
> + bne cr1,1f
> + lfd f0,128(r4)
> + fcmpu cr1,f0,f30
> + bne cr1,1f
> + lfd f0,136(r4)
> + fcmpu cr1,f0,f31
> + bne cr1,1f
> + li r3,0 #Sucess!!!
> +1: blr
> +
> +FUNC_START(test_fpu)
> + #r3 holds pointer to where to put the result of fork
> + #r4 holds pointer to the pid
> + #f14-f31 are non volatiles
> + PUSH_BASIC_STACK(256)
> + std r3,40(sp) #Address of darray
So, this could be:
PUSH_BASIC_STACK(256)
std r3,PPC_MIN_STACK+8(sp)
... though I wonder why there is +8 here?
- Naveen
More information about the Linuxppc-dev
mailing list