libitm/x86: Correct offsets of __private_tm and pointer_guard

Message ID 20180530145403.GA42666@intel.com
State New
Headers show
Series
  • libitm/x86: Correct offsets of __private_tm and pointer_guard
Related show

Commit Message

H.J. Lu May 30, 2018, 2:54 p.m.
In glibc, sysdeps/i386/nptl/tls.h has

typedef struct
{
  void *tcb;            /* Pointer to the TCB.  Not necessarily the
                           thread descriptor used by libpthread.  */
  dtv_t *dtv;
  void *self;           /* Pointer to the thread descriptor.  */
  int multiple_threads;
  uintptr_t sysinfo;
  uintptr_t stack_guard;
  uintptr_t pointer_guard;
  int gscope_flag;
  int __glibc_reserved1;
  /* Reservation of some values for the TM ABI.  */
  void *__private_tm[4];
  /* GCC split stack support.  */
  void *__private_ss;
} tcbhead_t;

and sysdeps/x86_64/nptl/tls.h has

typedef struct
{
  void *tcb;            /* Pointer to the TCB.  Not necessarily the
                           thread descriptor used by libpthread.  */
  dtv_t *dtv;
  void *self;           /* Pointer to the thread descriptor.  */
  int multiple_threads;
  int gscope_flag;
  uintptr_t sysinfo;
  uintptr_t stack_guard;
  uintptr_t pointer_guard;
  unsigned long int vgetcpu_cache[2];
  int __glibc_reserved1;
  int __glibc_unused1;
  /* Reservation of some values for the TM ABI.  */
  void *__private_tm[4];
  /* GCC split stack support.  */
  void *__private_ss;
  long int __glibc_reserved2;
  /* Must be kept even if it is no longer used by glibc since programs,
     like AddressSanitizer, depend on the size of tcbhead_t.  */
  __128bits __glibc_unused2[8][4] __attribute__ ((aligned (32)));

  void *__padding[8];
} tcbhead_t;

The offsets of __private_tm are

i386:   36 bytes
x32:    48 bytes
x86_64: 80 bytes

and the offsets of pointer_guard are:

i386:   24 bytes
x32:    28 bytes
x86_64: 48 bytes

Update SEG_READ and SEG_WRITE to use the offset of __private_tm as base
and correct the offset of pointer_guard for x32.

Tested on i686, x86-64 and x32.  OK for trunk and release branches?


H.J.
---
	PR libitm/85988
	* config/linux/x86/tls.h (SEG_READ): Use the offset of
	__private_tm as base.
	(SEG_WRITE): Likewise.
	(SEG_ENCODE_WRITE): Correct the offset of pointer_guard for x32.
	(gtm_thr): Replace SEG_READ(10) with SEG_READ(0).
	(set_gtm_thr): Replace SEG_WRITE(10) with SEG_WRITE(0).
	(abi_disp): Replace SEG_DECODE_READ(11) with SEG_DECODE_READ(1).
	(set_abi_disp): Replace SEG_ENCODE_WRITE(11) with
	SEG_ENCODE_WRITE(1).
---
 libitm/config/linux/x86/tls.h | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

-- 
2.17.0

Comments

Torvald Riegel June 12, 2018, 8:23 a.m. | #1
On Wed, 2018-05-30 at 07:54 -0700, H.J. Lu wrote:
> In glibc, sysdeps/i386/nptl/tls.h has

> 

> typedef struct

> {

>   void *tcb;            /* Pointer to the TCB.  Not necessarily the

>                            thread descriptor used by libpthread.  */

>   dtv_t *dtv;

>   void *self;           /* Pointer to the thread descriptor.  */

>   int multiple_threads;

>   uintptr_t sysinfo;

>   uintptr_t stack_guard;

>   uintptr_t pointer_guard;

>   int gscope_flag;

>   int __glibc_reserved1;

>   /* Reservation of some values for the TM ABI.  */

>   void *__private_tm[4];

>   /* GCC split stack support.  */

>   void *__private_ss;

> } tcbhead_t;

> 

> and sysdeps/x86_64/nptl/tls.h has

> 

> typedef struct

> {

>   void *tcb;            /* Pointer to the TCB.  Not necessarily the

>                            thread descriptor used by libpthread.  */

>   dtv_t *dtv;

>   void *self;           /* Pointer to the thread descriptor.  */

>   int multiple_threads;

>   int gscope_flag;

>   uintptr_t sysinfo;

>   uintptr_t stack_guard;

>   uintptr_t pointer_guard;

>   unsigned long int vgetcpu_cache[2];

>   int __glibc_reserved1;

>   int __glibc_unused1;

>   /* Reservation of some values for the TM ABI.  */

>   void *__private_tm[4];

>   /* GCC split stack support.  */

>   void *__private_ss;

>   long int __glibc_reserved2;

>   /* Must be kept even if it is no longer used by glibc since programs,

>      like AddressSanitizer, depend on the size of tcbhead_t.  */

>   __128bits __glibc_unused2[8][4] __attribute__ ((aligned (32)));

> 

>   void *__padding[8];

> } tcbhead_t;

> 

> The offsets of __private_tm are

> 

> i386:   36 bytes

> x32:    48 bytes

> x86_64: 80 bytes

> 

> and the offsets of pointer_guard are:

> 

> i386:   24 bytes

> x32:    28 bytes

> x86_64: 48 bytes

> 

> Update SEG_READ and SEG_WRITE to use the offset of __private_tm as base

> and correct the offset of pointer_guard for x32.

> 

> Tested on i686, x86-64 and x32.  OK for trunk and release branches?


The patch itself looks okay to me, but the commit message is pretty
cryptic.  I can't ack for release branches.
H.J. Lu June 12, 2018, 11:12 a.m. | #2
On Tue, Jun 12, 2018 at 1:23 AM, Torvald Riegel <triegel@redhat.com> wrote:
> On Wed, 2018-05-30 at 07:54 -0700, H.J. Lu wrote:

>> In glibc, sysdeps/i386/nptl/tls.h has

>>

>> typedef struct

>> {

>>   void *tcb;            /* Pointer to the TCB.  Not necessarily the

>>                            thread descriptor used by libpthread.  */

>>   dtv_t *dtv;

>>   void *self;           /* Pointer to the thread descriptor.  */

>>   int multiple_threads;

>>   uintptr_t sysinfo;

>>   uintptr_t stack_guard;

>>   uintptr_t pointer_guard;

>>   int gscope_flag;

>>   int __glibc_reserved1;

>>   /* Reservation of some values for the TM ABI.  */

>>   void *__private_tm[4];

>>   /* GCC split stack support.  */

>>   void *__private_ss;

>> } tcbhead_t;

>>

>> and sysdeps/x86_64/nptl/tls.h has

>>

>> typedef struct

>> {

>>   void *tcb;            /* Pointer to the TCB.  Not necessarily the

>>                            thread descriptor used by libpthread.  */

>>   dtv_t *dtv;

>>   void *self;           /* Pointer to the thread descriptor.  */

>>   int multiple_threads;

>>   int gscope_flag;

>>   uintptr_t sysinfo;

>>   uintptr_t stack_guard;

>>   uintptr_t pointer_guard;

>>   unsigned long int vgetcpu_cache[2];

>>   int __glibc_reserved1;

>>   int __glibc_unused1;

>>   /* Reservation of some values for the TM ABI.  */

>>   void *__private_tm[4];

>>   /* GCC split stack support.  */

>>   void *__private_ss;

>>   long int __glibc_reserved2;

>>   /* Must be kept even if it is no longer used by glibc since programs,

>>      like AddressSanitizer, depend on the size of tcbhead_t.  */

>>   __128bits __glibc_unused2[8][4] __attribute__ ((aligned (32)));

>>

>>   void *__padding[8];

>> } tcbhead_t;

>>

>> The offsets of __private_tm are

>>

>> i386:   36 bytes

>> x32:    48 bytes

>> x86_64: 80 bytes

>>

>> and the offsets of pointer_guard are:

>>

>> i386:   24 bytes

>> x32:    28 bytes

>> x86_64: 48 bytes

>>

>> Update SEG_READ and SEG_WRITE to use the offset of __private_tm as base

>> and correct the offset of pointer_guard for x32.

>>

>> Tested on i686, x86-64 and x32.  OK for trunk and release branches?

>

> The patch itself looks okay to me, but the commit message is pretty

> cryptic.  I can't ack for release branches.

>


I checked in the patch with the updated commit message:

https://gcc.gnu.org/ml/gcc-cvs/2018-06/msg00446.html

Jakub, is this OK for release branches.

Thanks.

-- 
H.J.

Patch

diff --git a/libitm/config/linux/x86/tls.h b/libitm/config/linux/x86/tls.h
index 5f3fd273c0e..ca6a5af3d4f 100644
--- a/libitm/config/linux/x86/tls.h
+++ b/libitm/config/linux/x86/tls.h
@@ -42,8 +42,8 @@  namespace GTM HIDDEN {
 
 #ifdef __x86_64__
 #ifdef __LP64__
-# define SEG_READ(OFS)		"movq\t%%fs:(" #OFS "*8),%0"
-# define SEG_WRITE(OFS)		"movq\t%0,%%fs:(" #OFS "*8)"
+# define SEG_READ(OFS)		"movq\t%%fs:(80+" #OFS "*8),%0"
+# define SEG_WRITE(OFS)		"movq\t%0,%%fs:(80+" #OFS "*8)"
 # define SEG_DECODE_READ(OFS)	SEG_READ(OFS) "\n\t" \
 				"rorq\t$17,%0\n\t" \
 				"xorq\t%%fs:48,%0"
@@ -52,18 +52,18 @@  namespace GTM HIDDEN {
 				SEG_WRITE(OFS)
 #else
 // For X32.
-# define SEG_READ(OFS)          "movl\t%%fs:(" #OFS "*4),%0"
-# define SEG_WRITE(OFS)         "movl\t%0,%%fs:(" #OFS "*4)"
+# define SEG_READ(OFS)          "movl\t%%fs:(48+" #OFS "*4),%0"
+# define SEG_WRITE(OFS)         "movl\t%0,%%fs:(48+" #OFS "*4)"
 # define SEG_DECODE_READ(OFS)   SEG_READ(OFS) "\n\t" \
 				"rorl\t$9,%0\n\t" \
-				"xorl\t%%fs:24,%0"
-# define SEG_ENCODE_WRITE(OFS)  "xorl\t%%fs:24,%0\n\t" \
+				"xorl\t%%fs:28,%0"
+# define SEG_ENCODE_WRITE(OFS)  "xorl\t%%fs:28,%0\n\t" \
 				"roll\t$9,%0\n\t" \
 				SEG_WRITE(OFS)
 #endif
 #else
-# define SEG_READ(OFS)  "movl\t%%gs:(" #OFS "*4),%0"
-# define SEG_WRITE(OFS) "movl\t%0,%%gs:(" #OFS "*4)"
+# define SEG_READ(OFS)  "movl\t%%gs:(36+" #OFS "*4),%0"
+# define SEG_WRITE(OFS) "movl\t%0,%%gs:(36+" #OFS "*4)"
 # define SEG_DECODE_READ(OFS)	SEG_READ(OFS) "\n\t" \
 				"rorl\t$9,%0\n\t" \
 				"xorl\t%%gs:24,%0"
@@ -75,26 +75,26 @@  namespace GTM HIDDEN {
 static inline struct gtm_thread *gtm_thr(void)
 {
   struct gtm_thread *r;
-  asm volatile (SEG_READ(10) : "=r"(r));
+  asm volatile (SEG_READ(0) : "=r"(r));
   return r;
 }
 
 static inline void set_gtm_thr(struct gtm_thread *x)
 {
-  asm volatile (SEG_WRITE(10) : : "r"(x));
+  asm volatile (SEG_WRITE(0) : : "r"(x));
 }
 
 static inline struct abi_dispatch *abi_disp(void)
 {
   struct abi_dispatch *r;
-  asm volatile (SEG_DECODE_READ(11) : "=r"(r));
+  asm volatile (SEG_DECODE_READ(1) : "=r"(r));
   return r;
 }
 
 static inline void set_abi_disp(struct abi_dispatch *x)
 {
   void *scratch;
-  asm volatile (SEG_ENCODE_WRITE(11) : "=r"(scratch) : "0"(x));
+  asm volatile (SEG_ENCODE_WRITE(1) : "=r"(scratch) : "0"(x));
 }
 
 #undef SEG_READ