qapi: Improve specificity of type/member descriptions
[qemu/armbru.git] / common-user / host / s390x / safe-syscall.inc.S
blob2ccbaa2402e038702d92b86de08f01a927bd618d
1 /*
2  * safe-syscall.inc.S : host-specific assembly fragment
3  * to handle signals occurring at the same time as system calls.
4  * This is intended to be included by common-user/safe-syscall.S
5  *
6  * Written by Richard Henderson <rth@twiddle.net>
7  * Copyright (C) 2016 Red Hat, Inc.
8  *
9  * This work is licensed under the terms of the GNU GPL, version 2 or later.
10  * See the COPYING file in the top-level directory.
11  */
13         .global safe_syscall_base
14         .global safe_syscall_start
15         .global safe_syscall_end
16         .type   safe_syscall_base, @function
18         /* This is the entry point for making a system call. The calling
19          * convention here is that of a C varargs function with the
20          * first argument an 'int *' to the signal_pending flag, the
21          * second one the system call number (as a 'long'), and all further
22          * arguments being syscall arguments (also 'long').
23          */
24 safe_syscall_base:
25         .cfi_startproc
26         stmg    %r6,%r15,48(%r15)       /* save all call-saved registers */
27         .cfi_offset %r15,-40
28         .cfi_offset %r14,-48
29         .cfi_offset %r13,-56
30         .cfi_offset %r12,-64
31         .cfi_offset %r11,-72
32         .cfi_offset %r10,-80
33         .cfi_offset %r9,-88
34         .cfi_offset %r8,-96
35         .cfi_offset %r7,-104
36         .cfi_offset %r6,-112
37         lgr     %r1,%r15
38         lg      %r0,8(%r15)             /* load eos */
39         aghi    %r15,-160
40         .cfi_adjust_cfa_offset 160
41         stg     %r1,0(%r15)             /* store back chain */
42         stg     %r0,8(%r15)             /* store eos */
44         /*
45          * The syscall calling convention isn't the same as the C one:
46          * we enter with r2 == &signal_pending
47          *               r3 == syscall number
48          *               r4, r5, r6, (stack) == syscall arguments
49          *               and return the result in r2
50          * and the syscall instruction needs
51          *               r1 == syscall number
52          *               r2 ... r7 == syscall arguments
53          *               and returns the result in r2
54          * Shuffle everything around appropriately.
55          */
56         lgr     %r8,%r2                 /* signal_pending pointer */
57         lgr     %r1,%r3                 /* syscall number */
58         lgr     %r2,%r4                 /* syscall args */
59         lgr     %r3,%r5
60         lgr     %r4,%r6
61         lmg     %r5,%r7,320(%r15)
63         /* This next sequence of code works in conjunction with the
64          * rewind_if_safe_syscall_function(). If a signal is taken
65          * and the interrupted PC is anywhere between 'safe_syscall_start'
66          * and 'safe_syscall_end' then we rewind it to 'safe_syscall_start'.
67          * The code sequence must therefore be able to cope with this, and
68          * the syscall instruction must be the final one in the sequence.
69          */
70 safe_syscall_start:
71         /* if signal_pending is non-zero, don't do the call */
72         icm     %r0,15,0(%r8)
73         jne     2f
74         svc     0
75 safe_syscall_end:
77         /* code path for having successfully executed the syscall */
78         lg      %r15,0(%r15)            /* load back chain */
79         .cfi_remember_state
80         .cfi_adjust_cfa_offset -160
81         lmg     %r6,%r15,48(%r15)       /* load saved registers */
83         lghi    %r0, -4095              /* check for syscall error */
84         clgr    %r2, %r0
85         blr     %r14                    /* return on success */
86         lcr     %r2, %r2                /* create positive errno */
87         jg      safe_syscall_set_errno_tail
88         .cfi_restore_state
90         /* code path when we didn't execute the syscall */
91 2:      lg      %r15,0(%r15)            /* load back chain */
92         .cfi_adjust_cfa_offset -160
93         lmg     %r6,%r15,48(%r15)       /* load saved registers */
94         lghi    %r2, QEMU_ERESTARTSYS
95         jg      safe_syscall_set_errno_tail
97         .cfi_endproc
98         .size   safe_syscall_base, .-safe_syscall_base