aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Liebler <stli@linux.vnet.ibm.com>2016-07-20 08:29:43 +0200
committerStefan Liebler <stli@linux.vnet.ibm.com>2016-07-20 08:29:43 +0200
commit1f16923552ec25f17d8624afcdf382591fe5733e (patch)
treef86b311a258396ddcfdb4b0cc03e3ee8d2ecddc5
parent4f69cc45bcbed1619b15c9632f3eb6a36590c7dd (diff)
downloadglibc-1f16923552ec25f17d8624afcdf382591fe5733e.tar
glibc-1f16923552ec25f17d8624afcdf382591fe5733e.tar.gz
glibc-1f16923552ec25f17d8624afcdf382591fe5733e.tar.bz2
glibc-1f16923552ec25f17d8624afcdf382591fe5733e.zip
S390: Do not clobber r13 with memcpy on 31bit with copies >1MB.
If the default memcpy variant is called with a length of >1MB on 31bit, r13 is clobbered as the algorithm is switching to mvcle. The mvcle code returns without restoring r13. All other cases are restoring r13. If memcpy is called from outside libc the ifunc resolver will only select this variant if running on machines older than z10. Otherwise or if memcpy is called from inside libc, this default memcpy variant is called. The testcase timezone/tst-tzset is triggering this issue in some combinations of gcc versions and optimization levels. This bug was introduced in commit 04bb21ac93e90d7696bcaf8febe2b2dd2d83585a and thus is a regression compared to former glibc 2.23 release. This patch removes the usage of r13 at all. Thus it is not saved and restored. The base address for execute-instruction is now stored in r5 which is obtained after r5 is not needed anymore as 256byte block counter. ChangeLog: * sysdeps/s390/s390-32/memcpy.S (memcpy): Eliminate the usage of r13 as it is not restored in mvcle case.
-rw-r--r--ChangeLog5
-rw-r--r--sysdeps/s390/s390-32/memcpy.S13
2 files changed, 10 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog
index a2939995d4..c5456d8c63 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2016-07-20 Stefan Liebler <stli@linux.vnet.ibm.com>
+
+ * sysdeps/s390/s390-32/memcpy.S (memcpy): Eliminate the usage
+ of r13 as it is not restored in mvcle case.
+
2016-07-19 Mike Frysinger <vapier@gentoo.org>
* sysdeps/unix/sysv/linux/microblaze/sysdep.h (inline_syscall0):
diff --git a/sysdeps/s390/s390-32/memcpy.S b/sysdeps/s390/s390-32/memcpy.S
index 6be5104b68..1a8bdbf3cc 100644
--- a/sysdeps/s390/s390-32/memcpy.S
+++ b/sysdeps/s390/s390-32/memcpy.S
@@ -42,20 +42,18 @@ ENTRY(memcpy)
.machine "g5"
lr %r1,%r2 # r1: Use as dest ; r2: Return dest
.L_G5_start:
- st %r13,52(%r15)
- .cfi_offset 13, -44
- basr %r13,0
-.L_G5_16:
ltr %r4,%r4
- je .L_G5_4
+ je .L_G5_99
ahi %r4,-1
lr %r5,%r4
srl %r5,8
ltr %r5,%r5
jne .L_G5_13
- ex %r4,.L_G5_17-.L_G5_16(%r13)
.L_G5_4:
- l %r13,52(%r15)
+ basr %r5,0
+.L_G5_16:
+ ex %r4,.L_G5_17-.L_G5_16(%r5)
+.L_G5_99:
br %r14
.L_G5_13:
chi %r5,4096 # Switch to mvcle for copies >1MB
@@ -65,7 +63,6 @@ ENTRY(memcpy)
la %r1,256(%r1)
la %r3,256(%r3)
brct %r5,.L_G5_12
- ex %r4,.L_G5_17-.L_G5_16(%r13)
j .L_G5_4
.L_G5_17:
mvc 0(1,%r1),0(%r3)