diff options
author | Adhemerval Zanella <azanella@linux.vnet.ibm.com> | 2014-11-07 12:34:52 -0500 |
---|---|---|
committer | Adhemerval Zanella <azanella@linux.vnet.ibm.com> | 2015-01-12 06:32:08 -0500 |
commit | 56cf2763819d2f721c98f2b8bcc04a3c673837d3 (patch) | |
tree | 5d2fde37897779f64b83951c1ef99406fd384055 /sysdeps/powerpc/nptl/tls.h | |
parent | 4b45943a6f62cfc239e79ad8902f5c7f71fd13ec (diff) | |
download | glibc-56cf2763819d2f721c98f2b8bcc04a3c673837d3.tar glibc-56cf2763819d2f721c98f2b8bcc04a3c673837d3.tar.gz glibc-56cf2763819d2f721c98f2b8bcc04a3c673837d3.tar.bz2 glibc-56cf2763819d2f721c98f2b8bcc04a3c673837d3.zip |
powerpc: abort transaction in syscalls
Linux kernel powerpc documentation states issuing a syscall inside a
transaction is not recommended and may lead to undefined behavior. It
also states syscalls does not abort transactoin neither they run in
transactional state.
To avoid side-effects being visible outside transactions, GLIBC with
lock elision enabled will issue a transaction abort instruction just
before all syscalls if hardware supports hardware transactions.
Diffstat (limited to 'sysdeps/powerpc/nptl/tls.h')
-rw-r--r-- | sysdeps/powerpc/nptl/tls.h | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/sysdeps/powerpc/nptl/tls.h b/sysdeps/powerpc/nptl/tls.h index 753381f95d..1f3d97a995 100644 --- a/sysdeps/powerpc/nptl/tls.h +++ b/sysdeps/powerpc/nptl/tls.h @@ -63,6 +63,8 @@ typedef union dtv are private. */ typedef struct { + /* Indicate if HTM capable (ISA 2.07). */ + int tm_capable; /* Reservation for Dynamic System Optimizer ABI. */ uintptr_t dso_slot2; uintptr_t dso_slot1; @@ -130,11 +132,17 @@ register void *__thread_register __asm__ ("r13"); special attention since 'errno' is not yet available and if the operation can cause a failure 'errno' must not be touched. */ # define TLS_INIT_TP(tcbp) \ - (__thread_register = (void *) (tcbp) + TLS_TCB_OFFSET, NULL) + ({ \ + __thread_register = (void *) (tcbp) + TLS_TCB_OFFSET; \ + THREAD_SET_TM_CAPABLE (GLRO (dl_hwcap2) & PPC_FEATURE2_HAS_HTM ? 1 : 0); \ + NULL; \ + }) /* Value passed to 'clone' for initialization of the thread register. */ # define TLS_DEFINE_INIT_TP(tp, pd) \ - void *tp = (void *) (pd) + TLS_TCB_OFFSET + TLS_PRE_TCB_SIZE + void *tp = (void *) (pd) + TLS_TCB_OFFSET + TLS_PRE_TCB_SIZE; \ + (((tcbhead_t *) ((char *) tp - TLS_TCB_OFFSET))[-1].tm_capable) = \ + THREAD_GET_TM_CAPABLE (); /* Return the address of the dtv for the current thread. */ # define THREAD_DTV() \ @@ -188,6 +196,13 @@ register void *__thread_register __asm__ ("r13"); + TLS_PRE_TCB_SIZE))[-1].pointer_guard \ = THREAD_GET_POINTER_GUARD()) +/* tm_capable field in TCB head. */ +# define THREAD_GET_TM_CAPABLE() \ + (((tcbhead_t *) ((char *) __thread_register \ + - TLS_TCB_OFFSET))[-1].tm_capable) +# define THREAD_SET_TM_CAPABLE(value) \ + (THREAD_GET_TM_CAPABLE () = (value)) + /* l_tls_offset == 0 is perfectly valid on PPC, so we have to use some different value to mean unset l_tls_offset. */ # define NO_TLS_OFFSET -1 |