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