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
6 * Copyright (C) 2022 Linaro, Ltd.
8 * This work is licensed under the terms of the GNU GPL, version 2 or later.
9 * See the COPYING file in the top-level directory.
13 * Standardize on the _CALL_FOO symbols used by GCC:
14 * Apple XCode does not define _CALL_DARWIN.
15 * Clang defines _CALL_ELF (64-bit) but not _CALL_SYSV (32-bit).
17 #if !defined(_CALL_SYSV) && \
18 !defined(_CALL_DARWIN) && \
19 !defined(_CALL_AIX) && \
21 # if defined(__APPLE__)
23 # elif defined(__ELF__) && TCG_TARGET_REG_BITS == 32
31 # error "Unsupported ABI"
35 .global safe_syscall_base
36 .global safe_syscall_start
37 .global safe_syscall_end
38 .type safe_syscall_base, @function
43 * This is the entry point for making a system call. The calling
44 * convention here is that of a C varargs function with the
45 * first argument an 'int *' to the signal_pending flag, the
46 * second one the system call number (as a 'long'), and all further
47 * arguments being syscall arguments (also 'long').
57 * We enter with r3 == &signal_pending
58 * r4 == syscall number
59 * r5 ... r10 == syscall arguments
60 * and return the result in r3
61 * and the syscall instruction needs
62 * r0 == syscall number
63 * r3 ... r8 == syscall arguments
64 * and returns the result in r3
65 * Shuffle everything around appropriately.
67 mr 30, 3 /* signal_pending */
68 mr 0, 4 /* syscall number */
69 mr 3, 5 /* syscall arguments */
77 * This next sequence of code works in conjunction with the
78 * rewind_if_safe_syscall_function(). If a signal is taken
79 * and the interrupted PC is anywhere between 'safe_syscall_start'
80 * and 'safe_syscall_end' then we rewind it to 'safe_syscall_start'.
81 * The code sequence must therefore be able to cope with this, and
82 * the syscall instruction must be the final one in the sequence.
85 /* if signal_pending is non-zero, don't do the call */
91 /* code path when we did execute the syscall */
92 lwz 30, 4(1) /* restore r30 */
93 addi 1, 1, 8 /* restore stack */
96 bnslr+ /* return on success */
97 b safe_syscall_set_errno_tail
99 /* code path when we didn't execute the syscall */
102 addi 3, 0, QEMU_ERESTARTSYS
103 b safe_syscall_set_errno_tail
107 .size safe_syscall_base, .-safe_syscall_base