about summary refs log tree commit diff
path: root/sysdeps/unix/sysv/linux/s390/s390-32/swapcontext.S
diff options
context:
space:
mode:
authorAndreas Krebbel <krebbel@linux.vnet.ibm.com>2014-01-07 09:37:31 +0100
committerAndreas Krebbel <krebbel@linux.vnet.ibm.com>2014-01-07 09:42:23 +0100
commit05d138ef07481b16f1aaee648798cc51182ec65e (patch)
tree1b3641bd6db26d0a000aa899b69b7107463b65e5 /sysdeps/unix/sysv/linux/s390/s390-32/swapcontext.S
parent93a45ff1ca6d459618bb0cf93580c4b2809a4b61 (diff)
downloadglibc-05d138ef07481b16f1aaee648798cc51182ec65e.tar.gz
glibc-05d138ef07481b16f1aaee648798cc51182ec65e.tar.xz
glibc-05d138ef07481b16f1aaee648798cc51182ec65e.zip
S/390: Make ucontext_t extendible.
Diffstat (limited to 'sysdeps/unix/sysv/linux/s390/s390-32/swapcontext.S')
-rw-r--r--sysdeps/unix/sysv/linux/s390/s390-32/swapcontext.S27
1 files changed, 21 insertions, 6 deletions
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/swapcontext.S b/sysdeps/unix/sysv/linux/s390/s390-32/swapcontext.S
index 6c40c994ef..41ede4b7b2 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/swapcontext.S
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/swapcontext.S
@@ -33,6 +33,9 @@
   other than the PRESERVED state.  */
 
 ENTRY(__swapcontext)
+	/* While not part of the ABI a system call never clobbers r0
+	   or r1.  So keeping the values here while calling
+	   rt_sigprocmask is ok.  */
 	lr	%r1,%r2
 	lr      %r0,%r3
 
@@ -62,19 +65,31 @@ ENTRY(__swapcontext)
 	std     %f14,SC_FPRS+112(%r1)
 	std     %f15,SC_FPRS+120(%r1)
 
-	/* Set __swapcontext return value to 0.  */
-	slr     %r2,%r2
-
 	/* Store access registers.  */
 	stam    %a0,%a15,SC_ACRS(%r1)
 
+	/* Set __swapcontext return value to 0.  */
+	slr     %r2,%r2
+
 	/* Store general purpose registers.  */
 	stm     %r0,%r15,SC_GPRS(%r1)
 
-	/* sigprocmask (SIG_SETMASK, &sc->sc_mask, NULL).  */
-	la      %r2,SIG_BLOCK
+	/* Copy uc_flags into the new ucontext_t.  */
 	lr	%r5,%r0
-	la	%r3,SC_MASK(%r5)
+	l	%r2,SC_FLGS(%r5)
+	st	%r2,SC_FLGS(%r1)
+
+	/* Save/restore the upper halfs if necessary.  */
+	tml	%r2,1   /* UCONTEXT_UC_FLAGS_HIGH_GPRS */
+	jz	0f
+	.machine	"z900"
+	.machinemode	"zarch_nohighgprs"
+	stmh	%r0,%r15,SC_HIGHGPRS(%r1)
+	lmh	%r0,%r15,SC_HIGHGPRS(%r5)
+
+	/* rt_sigprocmask (SIG_SETMASK, &sc->sc_mask, NULL, sigsetsize).  */
+0:	la      %r2,SIG_BLOCK
+	la      %r3,SC_MASK(%r5)
 	slr	%r4,%r4
 	lhi	%r5,_NSIG8
 	svc	SYS_ify(rt_sigprocmask)