| /* | 
 |  * sie64a.S - low level sie call | 
 |  * | 
 |  * Copyright IBM Corp. 2008,2010 | 
 |  * | 
 |  * This program is free software; you can redistribute it and/or modify | 
 |  * it under the terms of the GNU General Public License (version 2 only) | 
 |  * as published by the Free Software Foundation. | 
 |  * | 
 |  *    Author(s): Heiko Carstens <heiko.carstens@de.ibm.com> | 
 |  *		 Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com> | 
 |  */ | 
 |  | 
 | #include <linux/errno.h> | 
 | #include <asm/asm-offsets.h> | 
 | #include <asm/setup.h> | 
 | #include <asm/asm-offsets.h> | 
 | #include <asm/ptrace.h> | 
 | #include <asm/thread_info.h> | 
 |  | 
 | _TIF_EXIT_SIE = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING) | 
 |  | 
 | /* | 
 |  * offsets into stackframe | 
 |  * SP_	= offsets into stack sie64 is called with | 
 |  * SPI_ = offsets into irq stack | 
 |  */ | 
 | SP_GREGS = __SF_EMPTY | 
 | SP_HOOK  = __SF_EMPTY+8 | 
 | SP_GPP	 = __SF_EMPTY+16 | 
 | SPI_PSW  = STACK_FRAME_OVERHEAD + __PT_PSW | 
 |  | 
 |  | 
 | 	.macro SPP newpp | 
 | 	tm	__LC_MACHINE_FLAGS+6,0x20	# MACHINE_FLAG_SPP | 
 | 	jz	0f | 
 | 	.insn	s,0xb2800000,\newpp | 
 | 0: | 
 | 	.endm | 
 |  | 
 | sie_irq_handler: | 
 | 	SPP	__LC_CMF_HPP			# set host id | 
 | 	larl	%r2,sie_inst | 
 | 	clg	%r2,SPI_PSW+8(0,%r15)		# intercepted sie | 
 | 	jne	1f | 
 | 	xc	__LC_SIE_HOOK(8),__LC_SIE_HOOK | 
 | 	lg	%r2,__LC_THREAD_INFO		# pointer thread_info struct | 
 | 	tm	__TI_flags+7(%r2),_TIF_EXIT_SIE | 
 | 	jz	0f | 
 | 	larl	%r2,sie_exit			# work pending, leave sie | 
 | 	stg	%r2,__LC_RETURN_PSW+8 | 
 | 	br	%r14 | 
 | 0:	larl	%r2,sie_reenter			# re-enter with guest id | 
 | 	stg	%r2,__LC_RETURN_PSW+8 | 
 | 1:	br	%r14 | 
 |  | 
 | /* | 
 |  * sie64a calling convention: | 
 |  * %r2 pointer to sie control block | 
 |  * %r3 guest register save area | 
 |  */ | 
 | 	.globl	sie64a | 
 | sie64a: | 
 | 	stg	%r3,SP_GREGS(%r15)		# save guest register save area | 
 | 	stmg	%r6,%r14,__SF_GPRS(%r15)	# save registers on entry | 
 | 	lgr	%r14,%r2			# pointer to sie control block | 
 | 	larl	%r5,sie_irq_handler | 
 | 	stg	%r2,SP_GPP(%r15) | 
 | 	stg	%r5,SP_HOOK(%r15)		# save hook target | 
 | 	lmg	%r0,%r13,0(%r3)			# load guest gprs 0-13 | 
 | sie_reenter: | 
 | 	mvc	__LC_SIE_HOOK(8),SP_HOOK(%r15) | 
 | 	SPP	SP_GPP(%r15)			# set guest id | 
 | sie_inst: | 
 | 	sie	0(%r14) | 
 | 	xc	__LC_SIE_HOOK(8),__LC_SIE_HOOK | 
 | 	SPP	__LC_CMF_HPP			# set host id | 
 | sie_exit: | 
 | 	lg	%r14,SP_GREGS(%r15) | 
 | 	stmg	%r0,%r13,0(%r14)		# save guest gprs 0-13 | 
 | 	lghi	%r2,0 | 
 | 	lmg	%r6,%r14,__SF_GPRS(%r15) | 
 | 	br	%r14 | 
 |  | 
 | sie_err: | 
 | 	xc	__LC_SIE_HOOK(8),__LC_SIE_HOOK | 
 | 	SPP	__LC_CMF_HPP			# set host id | 
 | 	lg	%r14,SP_GREGS(%r15) | 
 | 	stmg	%r0,%r13,0(%r14)		# save guest gprs 0-13 | 
 | 	lghi	%r2,-EFAULT | 
 | 	lmg	%r6,%r14,__SF_GPRS(%r15) | 
 | 	br	%r14 | 
 |  | 
 | 	.section __ex_table,"a" | 
 | 	.quad	sie_inst,sie_err | 
 | 	.previous |