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 (2939B)


      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) 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 */
     12
     13	.global safe_syscall_base
     14	.global safe_syscall_start
     15	.global safe_syscall_end
     16	.type	safe_syscall_base, @function
     17
     18	.text
     19
     20	/* This is the entry point for making a system call. The calling
     21	 * convention here is that of a C varargs function with the
     22	 * first argument an 'int *' to the signal_pending flag, the
     23	 * second one the system call number (as a 'long'), and all further
     24	 * arguments being syscall arguments (also 'long').
     25	 * We return a long which is the syscall's return value, which
     26	 * may be negative-errno on failure. Conversion to the
     27	 * -1-and-errno-set convention is done by the calling wrapper.
     28	 */
     29#if _CALL_ELF == 2
     30safe_syscall_base:
     31	.cfi_startproc
     32	.localentry safe_syscall_base,0
     33#else
     34	.section ".opd","aw"
     35	.align	3
     36safe_syscall_base:
     37	.quad	.L.safe_syscall_base,.TOC.@tocbase,0
     38	.previous
     39.L.safe_syscall_base:
     40	.cfi_startproc
     41#endif
     42	/* We enter with r3 == *signal_pending
     43	 *               r4 == syscall number
     44	 *               r5 ... r10 == syscall arguments
     45	 *               and return the result in r3
     46	 * and the syscall instruction needs
     47	 *               r0 == syscall number
     48	 *               r3 ... r8 == syscall arguments
     49	 *               and returns the result in r3
     50	 * Shuffle everything around appropriately.
     51	 */
     52	std     14, 16(1) /* Preserve r14 in SP+16 */
     53	.cfi_offset 14, 16
     54	mr	14, 3	/* signal_pending */
     55	mr	0, 4	/* syscall number */
     56	mr	3, 5	/* syscall arguments */
     57	mr	4, 6
     58	mr	5, 7
     59	mr	6, 8
     60	mr	7, 9
     61	mr	8, 10
     62
     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	 */
     70safe_syscall_start:
     71	/* if signal_pending is non-zero, don't do the call */
     72	lwz	12, 0(14)
     73	cmpwi	0, 12, 0
     74	bne-	0f
     75	sc
     76safe_syscall_end:
     77	/* code path when we did execute the syscall */
     78	ld 14, 16(1) /* restore r14 to its original value */
     79	bnslr+
     80
     81	/* syscall failed; return negative errno */
     82	neg	3, 3
     83	blr
     84
     85	/* code path when we didn't execute the syscall */
     860:	addi	3, 0, -TARGET_ERESTARTSYS
     87	ld 14, 16(1) /* restore r14 to its original value */
     88	blr
     89	.cfi_endproc
     90
     91#if _CALL_ELF == 2
     92	.size	safe_syscall_base, .-safe_syscall_base
     93#else
     94	.size	safe_syscall_base, .-.L.safe_syscall_base
     95	.size	.L.safe_syscall_base, .-.L.safe_syscall_base
     96#endif