root/mtcp/tlsutil.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


   1 #ifndef TLSUTIL_H
   2 #define TLSUTIL_H
   3 
   4 /* These functions are not defined for x86_64. */
   5 #ifdef __i386__
   6 # define tls_get_thread_area(arg, myinfo_gs) \
   7   mtcp_sys_get_thread_area(arg)
   8 # define tls_set_thread_area(arg, myinfo_gs) \
   9   mtcp_sys_set_thread_area(arg)
  10 #endif
  11 
  12 #ifdef __x86_64__
  13 # include <asm/prctl.h>
  14 # include <sys/prctl.h>
  15 /* man arch_prctl has both signatures, and prctl.h above has no declaration.
  16  *  int arch_prctl(int code, unsigned long addr);
  17  *  int arch_prctl(int code, unsigned long addr);
  18  */
  19 
  20 int arch_prctl();
  21 #if 1
  22 // These calls need to be made from both DMTCP and mtcp_restart
  23 /* ARE THE _GS OPERATIONS NECESSARY? */
  24 #  define tls_get_thread_area(uinfo, myinfo_gs) \
  25     ( mtcp_inline_syscall(arch_prctl,2,ARCH_GET_FS, \
  26          (unsigned long int)(&(((struct user_desc *)uinfo)->base_addr))), \
  27       mtcp_inline_syscall(arch_prctl,2,ARCH_GET_GS, &myinfo_gs) \
  28     )
  29 #  define tls_set_thread_area(uinfo, myinfo_gs) \
  30     ( mtcp_inline_syscall(arch_prctl,2,ARCH_SET_FS, \
  31         *(unsigned long int *)&(((struct user_desc *)uinfo)->base_addr)), \
  32       mtcp_inline_syscall(arch_prctl,2,ARCH_SET_GS, myinfo_gs) \
  33     )
  34 # else
  35 /* ARE THE _GS OPERATIONS NECESSARY? */
  36 #  define tls_get_thread_area(uinfo, myinfo_gs) \
  37      ( arch_prctl(ARCH_GET_FS, \
  38          (unsigned long int)(&(((struct user_desc *)uinfo)->base_addr))), \
  39        arch_prctl(ARCH_GET_GS, &myinfo_gs) \
  40      )
  41 #  define tls_set_thread_area(uinfo, myinfo_gs) \
  42     ( arch_prctl(ARCH_SET_FS, \
  43         *(unsigned long int *)&(((struct user_desc *)uinfo)->base_addr)), \
  44       arch_prctl(ARCH_SET_GS, myinfo_gs) \
  45     )
  46 # endif
  47 #endif /* end __x86_64__ */
  48 
  49 #ifdef __arm__
  50 /* This allocation hack will work only if calls to mtcp_sys_get_thread_area
  51  * and mtcp_sys_get_thread_area are both inside the same file (mtcp.c).
  52  * This is all because get_thread_area is not implemented for arm.
  53  *     For ARM, the thread pointer seems to point to the next slot
  54  * after the 'struct pthread'.  Why??  So, we subtract that address.
  55  * After that, tid/pid will be located at  offset 104/108 as expected
  56  * for glibc-2.13.
  57  * NOTE:  'struct pthread' defined in glibc/nptl/descr.h
  58  *     The value below (1216) is current for glibc-2.13.
  59  *     May have to update 'sizeof(struct pthread)' for new versions of glibc.
  60  *     We can automate this by searching for negative offset from end
  61  *     of 'struct pthread' in tls_tid_offset, tls_pid_offset in mtcp.c.
  62  */
  63 
  64 #  define tls_get_thread_area(uinfo, myinfo_gs) \
  65   ({ asm volatile ("mrc     p15, 0, %0, c13, c0, 3  @ load_tp_hard\n\t" \
  66                    : "=r" (myinfo_gs) ); \
  67     myinfo_gs = myinfo_gs - 1216; /* sizeof(struct pthread) = 1216 */ \
  68     *(unsigned long int *)&(((struct user_desc *)uinfo)->base_addr) \
  69       = myinfo_gs; \
  70     myinfo_gs; })
  71 #  define tls_set_thread_area(uinfo, myinfo_gs) \
  72     ( myinfo_gs = \
  73         *(unsigned long int *)&(((struct user_desc *)uinfo)->base_addr), \
  74       (mtcp_sys_kernel_set_tls(myinfo_gs+1216), 0) \
  75       /* 0 return value at end means success */ )
  76 #endif /* end __arm__ */
  77 
  78 #ifdef __aarch64__
  79 /* This allocation hack will work only if calls to mtcp_sys_get_thread_area
  80  * and mtcp_sys_get_thread_area are both inside the same file (mtcp.c).
  81  * This is all because get_thread_area is not implemented for aarch64.
  82  *     For ARM, the thread pointer seems to point to the next slot
  83  * after the 'struct pthread'.  Why??  So, we subtract that address.
  84  * After that, tid/pid will be located at offset 208/212 as expected
  85  * for glibc-2.17.
  86  * NOTE:  'struct pthread' defined in glibc/nptl/descr.h
  87  *     The value below (1776) is current for glibc-2.17.
  88  #     See PORTING file for easy way to compute these numbers.
  89  *     May have to update 'sizeof(struct pthread)' for new versions of glibc.
  90  *     We can automate this by searching for negative offset from end
  91  *     of 'struct pthread' in tls_tid_offset, tls_pid_offset in mtcp.c.
  92  */
  93 /* NOTE:  We want 'sizeof(myinfo_gs) == sizeof(unsigned long int)' always. */
  94 #  define tls_get_thread_area(uinfo, myinfo_gs) \
  95   ({ asm volatile ("mrs   %0, tpidr_el0" \
  96                    : "=r" (myinfo_gs) ); \
  97     myinfo_gs = myinfo_gs - 1776; /* sizeof(struct pthread) = 1776 */ \
  98     *(unsigned long int *)&(((struct user_desc *)uinfo)->base_addr) \
  99       = myinfo_gs; \
 100     myinfo_gs; })
 101 #  define tls_set_thread_area(uinfo, myinfo_gs) \
 102    ({ myinfo_gs = \
 103       *(unsigned long int *)&(((struct user_desc *)uinfo)->base_addr); \
 104       myinfo_gs = myinfo_gs + 1776; \
 105       asm volatile ("msr     tpidr_el0, %[gs]" : : [gs] "r" (myinfo_gs) ); \
 106       0;  })
 107 #endif /* end __aarch64__ */
 108 
 109 #endif /* TLSUTIL_H */

/* [<][>][^][v][top][bottom][index][help] */