]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
powerpc: Fix VSCR position in ucontext (bug 24088)
authorRogerio Alves <rcardoso@linux.ibm.com>
Mon, 5 Nov 2018 16:18:38 +0000 (10:18 -0600)
committerTulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
Fri, 11 Jan 2019 17:17:25 +0000 (15:17 -0200)
This patch fix VSCR position on ucontext. VSCR was read in the wrong
position on ucontext structure because it was ignoring the machine
endianess.

[BZ #24088]
* sysdeps/unix/sysv/linux/powerpc/sys/ucontext.h (vscr_t): Added
ifdef to fix read of VSCR.
* sysdeps/powerpc/powerpc64/Makefile [$subdir == stdlib]: Add
tst-ucontext-ppc64-vscr.c to test list.
* sysdeps/powerpc/powerpc64/tst-ucontext-ppc64-vscr.c: New test file.

Reviewed-by: Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
ChangeLog
sysdeps/powerpc/powerpc64/Makefile
sysdeps/powerpc/powerpc64/tst-ucontext-ppc64-vscr.c [new file with mode: 0644]
sysdeps/unix/sysv/linux/powerpc/sys/ucontext.h

index c640abcc9d6a6d26ac18271127273760db051f4b..61703793258bfb26b754d7cd4d8627cf19a72e77 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2019-01-11  Rogerio A. Cardoso  <rcardoso@linux.ibm.com>
+
+       * sysdeps/unix/sysv/linux/powerpc/sys/ucontext.h (vscr_t): Added
+       ifdef to fix read of VSCR.
+       * sysdeps/powerpc/powerpc64/Makefile [$subdir == stdlib]: Add
+       tst-ucontext-ppc64-vscr.c to test list.
+       * sysdeps/powerpc/powerpc64/tst-ucontext-ppc64-vscr.c: New test file.
+
 2019-01-10  Andreas K. Hüttel  <dilfridge@gentoo.org>
 
        * resolv/tst-resolv-ai_idn-common.c (response): Avoid switch
index a0bd0c9504270a8767be0ccb0f4d398a95b43420..6e88df1d6968212b5b15d093e77a5f69fbc3ce18 100644 (file)
@@ -59,3 +59,8 @@ $(objpfx)tst-setjmp-bug21895-static.out: $(objpfx)setjmp-bug21895.so
 tst-setjmp-bug21895-static-ENV = \
        LD_LIBRARY_PATH=$(objpfx):$(common-objpfx):$(common-objpfx)setjmp:$(common-objpfx)elf
 endif
+
+ifeq ($(subdir),stdlib)
+CFLAGS-tst-ucontext-ppc64-vscr.c += -maltivec
+tests += tst-ucontext-ppc64-vscr
+endif
diff --git a/sysdeps/powerpc/powerpc64/tst-ucontext-ppc64-vscr.c b/sysdeps/powerpc/powerpc64/tst-ucontext-ppc64-vscr.c
new file mode 100644 (file)
index 0000000..2dcf5bb
--- /dev/null
@@ -0,0 +1,84 @@
+/* Test if POWER vscr read by ucontext.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <support/check.h>
+#include <sys/auxv.h>
+#include <ucontext.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <altivec.h>
+
+#define SAT 0x1
+
+/* This test is supported only on POWER 5 or higher.  */
+#define PPC_CPU_SUPPORTED (PPC_FEATURE_POWER5 | PPC_FEATURE_POWER5_PLUS | \
+                          PPC_FEATURE_ARCH_2_05 | PPC_FEATURE_ARCH_2_06 | \
+                          PPC_FEATURE2_ARCH_2_07)
+static int
+do_test (void)
+{
+
+  if (!(getauxval(AT_HWCAP2) & PPC_CPU_SUPPORTED))
+    {
+      if (!(getauxval(AT_HWCAP) & PPC_CPU_SUPPORTED))
+      FAIL_UNSUPPORTED("This test is unsupported on POWER < 5\n");
+    }
+
+  uint32_t vscr[4] __attribute__ ((aligned (16)));
+  uint32_t* vscr_ptr = vscr;
+  uint32_t vscr_word;
+  ucontext_t ucp;
+  __vector __int128_t v0 = {0};
+  __vector __int128_t v1 = {0};
+
+  /* Set SAT bit in VSCR register.  */
+  asm volatile (".machine push;\n"
+               ".machine \"power5\";\n"
+               "vspltisb %0,0;\n"
+               "vspltisb %1,-1;\n"
+               "vpkuwus %0,%0,%1;\n"
+               "mfvscr %0;\n"
+               "stvx %0,0,%2;\n"
+               ".machine pop;"
+               : "=v" (v0), "=v" (v1)
+               : "r" (vscr_ptr)
+               : "memory");
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+  vscr_word = vscr[0];
+#else
+  vscr_word = vscr[3];
+#endif
+
+  if ((vscr_word & SAT) != SAT)
+    {
+      FAIL_EXIT1("FAIL: SAT bit is not set.\n");
+    }
+
+  if (getcontext (&ucp))
+    {
+      FAIL_EXIT1("FAIL: getcontext error\n");
+    }
+  if (ucp.uc_mcontext.v_regs->vscr.vscr_word != vscr_word)
+    {
+      FAIL_EXIT1("FAIL: ucontext vscr does not match with vscr\n");
+    }
+  return 0;
+}
+
+#include <support/test-driver.c>
index ccd49928068e70f695a0e5a36b3c0c8e88d23a26..95142401a3792104e138dacf7f78f463fa995c8c 100644 (file)
@@ -98,8 +98,13 @@ typedef double fpregset_t[__NFPREG];
    a whole quadword speedup save/restore.  */
 typedef struct _libc_vscr
 {
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
        unsigned int __pad[3];
        unsigned int __ctx(vscr_word);
+#else
+       unsigned int __ctx(vscr_word);
+       unsigned int __pad[3];
+#endif
 } vscr_t;
 
 /* Container for Altivec/VMX registers and status.