 6cde51769e
			
		
	
	
		6cde51769e
		
	
	
	
	
		
			
			The LT instruction was added in the extended immediate facility introduced with the z9-109 processor. Cc: Riku Voipio <riku.voipio@iki.fi> Reported-by: Michael Tokarev <mjt@tls.msk.ru> Fixes: c9bc3437a905b660561a26cd4ecc64579843267b Suggested-by: Aurelien Jarno <aurelien@aurel32.net> Reviewed-by: Thomas Huth <thuth@redhat.com> Signed-off-by: Richard Henderson <rth@twiddle.net> Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
		
			
				
	
	
		
			91 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
			
		
		
	
	
			91 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
| /*
 | |
|  * safe-syscall.inc.S : host-specific assembly fragment
 | |
|  * to handle signals occurring at the same time as system calls.
 | |
|  * This is intended to be included by linux-user/safe-syscall.S
 | |
|  *
 | |
|  * Written by Richard Henderson <rth@twiddle.net>
 | |
|  * Copyright (C) 2016 Red Hat, Inc.
 | |
|  *
 | |
|  * This work is licensed under the terms of the GNU GPL, version 2 or later.
 | |
|  * See the COPYING file in the top-level directory.
 | |
|  */
 | |
| 
 | |
| 	.global safe_syscall_base
 | |
| 	.global safe_syscall_start
 | |
| 	.global safe_syscall_end
 | |
| 	.type	safe_syscall_base, @function
 | |
| 
 | |
| 	/* This is the entry point for making a system call. The calling
 | |
| 	 * convention here is that of a C varargs function with the
 | |
| 	 * first argument an 'int *' to the signal_pending flag, the
 | |
| 	 * second one the system call number (as a 'long'), and all further
 | |
| 	 * arguments being syscall arguments (also 'long').
 | |
| 	 * We return a long which is the syscall's return value, which
 | |
| 	 * may be negative-errno on failure. Conversion to the
 | |
| 	 * -1-and-errno-set convention is done by the calling wrapper.
 | |
| 	 */
 | |
| safe_syscall_base:
 | |
| 	.cfi_startproc
 | |
| 	stmg	%r6,%r15,48(%r15)	/* save all call-saved registers */
 | |
| 	.cfi_offset %r15,-40
 | |
| 	.cfi_offset %r14,-48
 | |
| 	.cfi_offset %r13,-56
 | |
| 	.cfi_offset %r12,-64
 | |
| 	.cfi_offset %r11,-72
 | |
| 	.cfi_offset %r10,-80
 | |
| 	.cfi_offset %r9,-88
 | |
| 	.cfi_offset %r8,-96
 | |
| 	.cfi_offset %r7,-104
 | |
| 	.cfi_offset %r6,-112
 | |
| 	lgr	%r1,%r15
 | |
| 	lg	%r0,8(%r15)		/* load eos */
 | |
| 	aghi	%r15,-160
 | |
| 	.cfi_adjust_cfa_offset 160
 | |
| 	stg	%r1,0(%r15)		/* store back chain */
 | |
| 	stg	%r0,8(%r15)		/* store eos */
 | |
| 
 | |
| 	/* The syscall calling convention isn't the same as the
 | |
| 	 * C one:
 | |
| 	 * we enter with r2 == *signal_pending
 | |
| 	 *               r3 == syscall number
 | |
| 	 *               r4, r5, r6, (stack) == syscall arguments
 | |
| 	 *               and return the result in r2
 | |
| 	 * and the syscall instruction needs
 | |
| 	 *               r1 == syscall number
 | |
| 	 *               r2 ... r7 == syscall arguments
 | |
| 	 *               and returns the result in r2
 | |
| 	 * Shuffle everything around appropriately.
 | |
| 	 */
 | |
| 	lgr	%r8,%r2			/* signal_pending pointer */
 | |
| 	lgr	%r1,%r3			/* syscall number */
 | |
| 	lgr	%r2,%r4			/* syscall args */
 | |
| 	lgr	%r3,%r5
 | |
| 	lgr	%r4,%r6
 | |
| 	lmg	%r5,%r7,320(%r15)
 | |
| 
 | |
| 	/* This next sequence of code works in conjunction with the
 | |
| 	 * rewind_if_safe_syscall_function(). If a signal is taken
 | |
| 	 * and the interrupted PC is anywhere between 'safe_syscall_start'
 | |
| 	 * and 'safe_syscall_end' then we rewind it to 'safe_syscall_start'.
 | |
| 	 * The code sequence must therefore be able to cope with this, and
 | |
| 	 * the syscall instruction must be the final one in the sequence.
 | |
| 	 */
 | |
| safe_syscall_start:
 | |
| 	/* if signal_pending is non-zero, don't do the call */
 | |
| 	icm	%r0,15,0(%r8)
 | |
| 	jne	2f
 | |
| 	svc	0
 | |
| safe_syscall_end:
 | |
| 
 | |
| 1:	lg	%r15,0(%r15)		/* load back chain */
 | |
| 	.cfi_remember_state
 | |
| 	.cfi_adjust_cfa_offset -160
 | |
| 	lmg	%r6,%r15,48(%r15)	/* load saved registers */
 | |
| 	br	%r14
 | |
| 	.cfi_restore_state
 | |
| 2:	lghi	%r2, -TARGET_ERESTARTSYS
 | |
| 	j	1b
 | |
| 	.cfi_endproc
 | |
| 
 | |
| 	.size	safe_syscall_base, .-safe_syscall_base
 |