Blame SOURCES/glibc-rh731835-1.patch

147e83
commit 56cf2763819d2f721c98f2b8bcc04a3c673837d3
147e83
Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
147e83
Date:   Fri Nov 7 12:34:52 2014 -0500
147e83
147e83
    powerpc: abort transaction in syscalls
147e83
    
147e83
    Linux kernel powerpc documentation states issuing a syscall inside a
147e83
    transaction is not recommended and may lead to undefined behavior. It
147e83
    also states syscalls does not abort transactoin neither they run in
147e83
    transactional state.
147e83
    
147e83
    To avoid side-effects being visible outside transactions, GLIBC with
147e83
    lock elision enabled will issue a transaction abort instruction just
147e83
    before all syscalls if hardware supports hardware transactions.
147e83
147e83
Index: glibc-2.17-c758a686/nptl/sysdeps/powerpc/tcb-offsets.sym
147e83
===================================================================
147e83
--- glibc-2.17-c758a686.orig/nptl/sysdeps/powerpc/tcb-offsets.sym
147e83
+++ glibc-2.17-c758a686/nptl/sysdeps/powerpc/tcb-offsets.sym
147e83
@@ -15,6 +15,7 @@ MULTIPLE_THREADS_OFFSET		thread_offsetof
147e83
 PID				thread_offsetof (pid)
147e83
 TID				thread_offsetof (tid)
147e83
 POINTER_GUARD			(offsetof (tcbhead_t, pointer_guard) - TLS_TCB_OFFSET - sizeof (tcbhead_t))
147e83
+TM_CAPABLE			(offsetof (tcbhead_t, tm_capable) - TLS_TCB_OFFSET - sizeof (tcbhead_t))
147e83
 #ifndef __ASSUME_PRIVATE_FUTEX
147e83
 PRIVATE_FUTEX_OFFSET		thread_offsetof (header.private_futex)
147e83
 #endif
147e83
Index: glibc-2.17-c758a686/nptl/sysdeps/powerpc/tls.h
147e83
===================================================================
147e83
--- glibc-2.17-c758a686.orig/nptl/sysdeps/powerpc/tls.h
147e83
+++ glibc-2.17-c758a686/nptl/sysdeps/powerpc/tls.h
147e83
@@ -61,6 +61,15 @@ typedef union dtv
147e83
    are private.  */
147e83
 typedef struct
147e83
 {
147e83
+  /* Indicate if HTM capable (ISA 2.07).  */
147e83
+  uint32_t tm_capable;
147e83
+  /* Reservation for AT_PLATFORM data - powerpc64.  */
147e83
+#ifdef __powerpc64__
147e83
+  uint32_t at_platform;
147e83
+#endif
147e83
+  /* Reservation for Dynamic System Optimizer ABI.  */
147e83
+  uintptr_t dso_slot2;
147e83
+  uintptr_t dso_slot1;
147e83
   /* GCC split stack support.  */
147e83
   void *__private_ss;
147e83
   /* Reservation for the Event-Based Branching ABI.  */
147e83
@@ -123,7 +132,11 @@ register void *__thread_register __asm__
147e83
    special attention since 'errno' is not yet available and if the
147e83
    operation can cause a failure 'errno' must not be touched.  */
147e83
 # define TLS_INIT_TP(tcbp, secondcall) \
147e83
-    (__thread_register = (void *) (tcbp) + TLS_TCB_OFFSET, NULL)
147e83
+  ({ 									      \
147e83
+    __thread_register = (void *) (tcbp) + TLS_TCB_OFFSET;		      \
147e83
+    THREAD_SET_TM_CAPABLE (GLRO (dl_hwcap2) & PPC_FEATURE2_HAS_HTM ? 1 : 0);  \
147e83
+    NULL;								      \
147e83
+  })
147e83
 
147e83
 /* Return the address of the dtv for the current thread.  */
147e83
 # define THREAD_DTV() \
147e83
@@ -177,6 +190,13 @@ register void *__thread_register __asm__
147e83
 		     + TLS_PRE_TCB_SIZE))[-1].pointer_guard		      \
147e83
      = THREAD_GET_POINTER_GUARD())
147e83
 
147e83
+/* tm_capable field in TCB head.  */
147e83
+# define THREAD_GET_TM_CAPABLE() \
147e83
+    (((tcbhead_t *) ((char *) __thread_register				      \
147e83
+		     - TLS_TCB_OFFSET))[-1].tm_capable)
147e83
+# define THREAD_SET_TM_CAPABLE(value) \
147e83
+    (THREAD_GET_TM_CAPABLE () = (value))
147e83
+
147e83
 /* l_tls_offset == 0 is perfectly valid on PPC, so we have to use some
147e83
    different value to mean unset l_tls_offset.  */
147e83
 # define NO_TLS_OFFSET		-1
147e83
Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/sysdep.h
147e83
===================================================================
147e83
--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/sysdep.h
147e83
+++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/sysdep.h
147e83
@@ -89,7 +89,23 @@ GOT_LABEL:			;					      \
147e83
   cfi_endproc;								      \
147e83
   ASM_SIZE_DIRECTIVE(name)
147e83
 
147e83
+#if ! IS_IN(rtld) && defined (ENABLE_LOCK_ELISION)
147e83
+# define ABORT_TRANSACTION \
147e83
+    cmpwi    2,0;		\
147e83
+    beq      1f;		\
147e83
+    lwz      0,TM_CAPABLE(2);	\
147e83
+    cmpwi    0,0;		\
147e83
+    beq	     1f;		\
147e83
+    li	     0,_ABORT_SYSCALL;	\
147e83
+    tabort.  0;			\
147e83
+    .align 4;			\
147e83
+1:
147e83
+#else
147e83
+# define ABORT_TRANSACTION
147e83
+#endif
147e83
+
147e83
 #define DO_CALL(syscall)						      \
147e83
+    ABORT_TRANSACTION							      \
147e83
     li 0,syscall;							      \
147e83
     sc
147e83
 
147e83
Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/sysdep.h
147e83
===================================================================
147e83
--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/sysdep.h
147e83
+++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/sysdep.h
147e83
@@ -283,7 +283,23 @@ LT_LABELSUFFIX(name,_name_end): ; \
147e83
   TRACEBACK_MASK(name,mask)	\
147e83
   END_2(name)
147e83
 
147e83
+#if !IS_IN(rtld) && defined (ENABLE_LOCK_ELISION)
147e83
+# define ABORT_TRANSACTION \
147e83
+    cmpdi    13,0;		\
147e83
+    beq      1f;		\
147e83
+    lwz      0,TM_CAPABLE(13);	\
147e83
+    cmpwi    0,0;		\
147e83
+    beq	     1f;		\
147e83
+    li	     0,_ABORT_SYSCALL;	\
147e83
+    tabort.  0;			\
147e83
+    .align 4;                   \
147e83
+1:
147e83
+#else
147e83
+# define ABORT_TRANSACTION
147e83
+#endif
147e83
+
147e83
 #define DO_CALL(syscall) \
147e83
+    ABORT_TRANSACTION \
147e83
     li 0,syscall; \
147e83
     sc
147e83
 
147e83
Index: glibc-2.17-c758a686/sysdeps/powerpc/sysdep.h
147e83
===================================================================
147e83
--- glibc-2.17-c758a686.orig/sysdeps/powerpc/sysdep.h
147e83
+++ glibc-2.17-c758a686/sysdeps/powerpc/sysdep.h
147e83
@@ -21,6 +21,10 @@
147e83
  */
147e83
 #define _SYS_AUXV_H 1
147e83
 #include <bits/hwcap.h>
147e83
+#ifdef ENABLE_LOCK_ELISION
147e83
+#include <tls.h>
147e83
+#include <htm.h>
147e83
+#endif
147e83
 
147e83
 #define PPC_FEATURE_970 (PPC_FEATURE_POWER4 + PPC_FEATURE_HAS_ALTIVEC)
147e83
 
147e83
@@ -164,4 +168,22 @@
147e83
 #define ALIGNARG(log2) log2
147e83
 #define ASM_SIZE_DIRECTIVE(name) .size name,.-name
147e83
 
147e83
+#else
147e83
+
147e83
+/* Linux kernel powerpc documentation [1] states issuing a syscall inside a
147e83
+   transaction is not recommended and may lead to undefined behavior.  It
147e83
+   also states syscalls do not abort transactions.  To avoid such traps,
147e83
+   we abort transaction just before syscalls.
147e83
+
147e83
+   [1] Documentation/powerpc/transactional_memory.txt [Syscalls]  */
147e83
+#if !IS_IN(rtld) && defined (ENABLE_LOCK_ELISION)
147e83
+# define ABORT_TRANSACTION \
147e83
+  ({ 						\
147e83
+    if (THREAD_GET_TM_CAPABLE ())		\
147e83
+      __builtin_tabort (_ABORT_SYSCALL);	\
147e83
+  })
147e83
+#else
147e83
+# define ABORT_TRANSACTION
147e83
+#endif
147e83
+
147e83
 #endif	/* __ASSEMBLER__ */
147e83
Index: glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h
147e83
===================================================================
147e83
--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h
147e83
+++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h
147e83
@@ -194,6 +194,7 @@
147e83
     register long int r11 __asm__ ("r11");				\
147e83
     register long int r12 __asm__ ("r12");				\
147e83
     LOADARGS_##nr(name, args);						\
147e83
+    ABORT_TRANSACTION;							\
147e83
     __asm__ __volatile__						\
147e83
       ("sc   \n\t"							\
147e83
        "mfcr %0"							\
147e83
Index: glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h
147e83
===================================================================
147e83
--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h
147e83
+++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h
147e83
@@ -201,6 +201,7 @@
147e83
     register long int r7  __asm__ ("r7");				\
147e83
     register long int r8  __asm__ ("r8");				\
147e83
     LOADARGS_##nr (name, ##args);					\
147e83
+    ABORT_TRANSACTION;							\
147e83
     __asm__ __volatile__						\
147e83
       ("sc\n\t"								\
147e83
        "mfcr  %0\n\t"							\
147e83
Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/createthread.c
147e83
===================================================================
147e83
--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/powerpc/createthread.c
147e83
+++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/createthread.c
147e83
@@ -16,9 +16,16 @@
147e83
    License along with the GNU C Library; if not, see
147e83
    <http://www.gnu.org/licenses/>.  */
147e83
 
147e83
+/* RHEL 7-specific changes: The functions PREPARE_CREATE and TLS_VALUE
147e83
+   are used by createthread.c to override thread setup.  In upstream
147e83
+   they appear in TLS_DEFINE_INIT_TP.  */
147e83
+# define PREPARE_CREATE \
147e83
+  void *tp = (void *) (pd) + TLS_TCB_OFFSET + TLS_PRE_TCB_SIZE;            \
147e83
+  (((tcbhead_t *) ((char *) tp - TLS_TCB_OFFSET))[-1].tm_capable) =        \
147e83
+  THREAD_GET_TM_CAPABLE ();
147e83
+
147e83
 /* Value passed to 'clone' for initialization of the thread register.  */
147e83
-#define TLS_VALUE ((void *) (pd) \
147e83
-		   + TLS_TCB_OFFSET + TLS_PRE_TCB_SIZE)
147e83
+# define TLS_VALUE tp
147e83
 
147e83
 /* Get the real implementation.	 */
147e83
 #include <nptl/sysdeps/pthread/createthread.c>