Merge tag 'powerpc-4.9-1' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc...
[cascardo/linux.git] / tools / testing / selftests / powerpc / tm / tm-signal.S
1 /*
2  * Copyright 2015, Cyril Bur, IBM Corp.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version
7  * 2 of the License, or (at your option) any later version.
8  */
9
10 #include "../basic_asm.h"
11 #include "../gpr_asm.h"
12 #include "../fpu_asm.h"
13 #include "../vmx_asm.h"
14 #include "../vsx_asm.h"
15
16 /*
17  * Large caveat here being that the caller cannot expect the
18  * signal to always be sent! The hardware can (AND WILL!) abort
19  * the transaction between the tbegin and the tsuspend (however
20  * unlikely it seems or infrequently it actually happens).
21  * You have been warned.
22  */
23 /* long tm_signal_self(pid_t pid, long *gprs, double *fps, vector *vms, vector *vss); */
24 FUNC_START(tm_signal_self_context_load)
25         PUSH_BASIC_STACK(512)
26         /*
27          * Don't strictly need to save and restore as it depends on if
28          * we're going to use them, however this reduces messy logic
29          */
30         PUSH_VMX(STACK_FRAME_LOCAL(5,0),r8)
31         PUSH_FPU(512)
32         PUSH_NVREGS_BELOW_FPU(512)
33         std r3, STACK_FRAME_PARAM(0)(sp) /* pid */
34         std r4, STACK_FRAME_PARAM(1)(sp) /* gps */
35         std r5, STACK_FRAME_PARAM(2)(sp) /* fps */
36         std r6, STACK_FRAME_PARAM(3)(sp) /* vms */
37         std r7, STACK_FRAME_PARAM(4)(sp) /* vss */
38
39         ld r3, STACK_FRAME_PARAM(1)(sp)
40         cmpdi r3, 0
41         beq skip_gpr_lc
42         bl load_gpr
43 skip_gpr_lc:
44         ld r3, STACK_FRAME_PARAM(2)(sp)
45         cmpdi   r3, 0
46         beq     skip_fpu_lc
47         bl load_fpu
48 skip_fpu_lc:
49         ld r3, STACK_FRAME_PARAM(3)(sp)
50         cmpdi r3, 0
51         beq     skip_vmx_lc
52         bl load_vmx
53 skip_vmx_lc:
54         ld r3, STACK_FRAME_PARAM(4)(sp)
55         cmpdi   r3, 0
56         beq     skip_vsx_lc
57         bl load_vsx
58 skip_vsx_lc:
59         /*
60          * Set r3 (return value) before tbegin. Use the pid as a known
61          * 'all good' return value, zero is used to indicate a non-doomed
62          * transaction.
63          */
64         ld      r3, STACK_FRAME_PARAM(0)(sp)
65         tbegin.
66         beq     1f
67         tsuspend. /* Can't enter a syscall transactionally */
68         ld      r3, STACK_FRAME_PARAM(1)(sp)
69         cmpdi   r3, 0
70         beq skip_gpr_lt
71         /* Get the second half of the array */
72         addi    r3, r3, 8 * 18
73         bl load_gpr
74 skip_gpr_lt:
75         ld r3, STACK_FRAME_PARAM(2)(sp)
76         cmpdi   r3, 0
77         beq     skip_fpu_lt
78         /* Get the second half of the array */
79         addi    r3, r3, 8 * 18
80         bl load_fpu
81 skip_fpu_lt:
82         ld r3, STACK_FRAME_PARAM(3)(sp)
83         cmpdi r3, 0
84         beq     skip_vmx_lt
85         /* Get the second half of the array */
86         addi    r3, r3, 16 * 12
87         bl load_vmx
88 skip_vmx_lt:
89         ld r3, STACK_FRAME_PARAM(4)(sp)
90         cmpdi   r3, 0
91         beq     skip_vsx_lt
92         /* Get the second half of the array */
93         addi    r3, r3, 16 * 12
94         bl load_vsx
95 skip_vsx_lt:
96         li      r0, 37 /* sys_kill */
97         ld r3, STACK_FRAME_PARAM(0)(sp) /* pid */
98         li r4, 10 /* SIGUSR1 */
99         sc /* Taking the signal will doom the transaction */
100         tabort. 0
101         tresume. /* Be super sure we abort */
102         /*
103          * This will cause us to resume doomed transaction and cause
104          * hardware to cleanup, we'll end up at 1: anything between
105          * tresume. and 1: shouldn't ever run.
106          */
107         li r3, 0
108         1:
109         POP_VMX(STACK_FRAME_LOCAL(5,0),r4)
110         POP_FPU(512)
111         POP_NVREGS_BELOW_FPU(512)
112         POP_BASIC_STACK(512)
113         blr
114 FUNC_END(tm_signal_self_context_load)