cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

safe-syscall.inc.S (2528B)


      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 linux-user/safe-syscall.S
      5 *
      6 * Written by Richard Henderson <rth@twiddle.net>
      7 * Copyright (C) 2018 Linaro, 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 */
     12
     13	.global safe_syscall_base
     14	.global safe_syscall_start
     15	.global safe_syscall_end
     16	.type	safe_syscall_base, @function
     17	.type	safe_syscall_start, @function
     18	.type	safe_syscall_end, @function
     19
     20	/*
     21	 * This is the entry point for making a system call. The calling
     22	 * convention here is that of a C varargs function with the
     23	 * first argument an 'int *' to the signal_pending flag, the
     24	 * second one the system call number (as a 'long'), and all further
     25	 * arguments being syscall arguments (also 'long').
     26	 * We return a long which is the syscall's return value, which
     27	 * may be negative-errno on failure. Conversion to the
     28	 * -1-and-errno-set convention is done by the calling wrapper.
     29	 */
     30safe_syscall_base:
     31	.cfi_startproc
     32	/*
     33	 * The syscall calling convention is nearly the same as C:
     34	 * we enter with a0 == *signal_pending
     35	 *               a1 == syscall number
     36	 *               a2 ... a7 == syscall arguments
     37	 *               and return the result in a0
     38	 * and the syscall instruction needs
     39	 *               a7 == syscall number
     40	 *               a0 ... a5 == syscall arguments
     41	 *               and returns the result in a0
     42	 * Shuffle everything around appropriately.
     43	 */
     44	mv	t0, a0		/* signal_pending pointer */
     45	mv	t1, a1		/* syscall number */
     46	mv	a0, a2		/* syscall arguments */
     47	mv	a1, a3
     48	mv	a2, a4
     49	mv	a3, a5
     50	mv	a4, a6
     51	mv	a5, a7
     52	mv	a7, t1
     53
     54	/*
     55	 * This next sequence of code works in conjunction with the
     56	 * rewind_if_safe_syscall_function(). If a signal is taken
     57	 * and the interrupted PC is anywhere between 'safe_syscall_start'
     58	 * and 'safe_syscall_end' then we rewind it to 'safe_syscall_start'.
     59	 * The code sequence must therefore be able to cope with this, and
     60	 * the syscall instruction must be the final one in the sequence.
     61	 */
     62safe_syscall_start:
     63	/* If signal_pending is non-zero, don't do the call */
     64	lw	t1, 0(t0)
     65	bnez	t1, 0f
     66	scall
     67safe_syscall_end:
     68	/* code path for having successfully executed the syscall */
     69	ret
     70
     710:
     72	/* code path when we didn't execute the syscall */
     73	li	a0, -TARGET_ERESTARTSYS
     74	ret
     75	.cfi_endproc
     76
     77	.size	safe_syscall_base, .-safe_syscall_base