This is the mail archive of the glibc-cvs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

GNU C Library master sources branch master updated. glibc-2.27.9000-209-gf8baf2a


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".

The branch, master has been updated
       via  f8baf2a2242029600beb213d3f042e7c0482e502 (commit)
      from  c553cd6f7e939ae4ef62b52b3c55fbe76dddecee (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=f8baf2a2242029600beb213d3f042e7c0482e502

commit f8baf2a2242029600beb213d3f042e7c0482e502
Author: Samuel Thibault <samuel.thibault@ens-lyon.org>
Date:   Sat Mar 17 03:17:36 2018 +0100

    hurd: add TLS support
    
    	* sysdeps/generic/thread_state.h (MACHINE_NEW_THREAD_STATE_FLAVOR):
    	Define macro.
    	* sysdeps/mach/thread_state.h (MACHINE_THREAD_STATE_FIX_NEW): New macro.
    	* sysdeps/mach/i386/thread_state.h
    	(MACHINE_NEW_THREAD_STATE_FLAVOR): New macro, defined to
    	i386_THREAD_STATE.
    	(MACHINE_THREAD_STATE_FLAVOR): Define to i386_REGS_SEGS_STATE instead of
    	i386_THREAD_STATE.
    	(MACHINE_THREAD_STATE_FIX_NEW): New macro, reads segments.
    
    	* sysdeps/mach/hurd/i386/trampoline.c (_hurd_setup_sighandler): Use
    	i386_REGS_SEGS_STATE instead of i386_THREAD_STATE.
    
    	* sysdeps/mach/hurd/i386/tls.h (TCB_ALIGNMENT, HURD_SEL_LDT): New
    	macros.
    	(_hurd_tls_fork): Add original thread parameter, Duplicate existing LDT
    	descriptor instead of creating a new one.
    	(_hurd_tls_new): New function, creates a new descriptor and updates tcb.
    
    	* mach/setup-thread.c: Include <ldsodefs.h>.
    	(__mach_setup_thread): Call _dl_allocate_tls, pass
    	MACHINE_NEW_THREAD_STATE_FLAVOR to __thread_set_state instead of
    	MACHINE_THREAD_STATE_FLAVOR, before getting
    	MACHINE_THREAD_STATE_FLAVOR, calling _hurd_tls_new, and setting
    	MACHINE_THREAD_STATE_FLAVOR with the result.
    	* hurd/hurdfault.c (_hurdsig_fault_init): Call
    	MACHINE_THREAD_STATE_FIX_NEW.
    	* sysdeps/mach/hurd/fork.c (__fork): Call _hurd_tls_fork for sigthread
    	too.  Add original thread parameter.

diff --git a/ChangeLog b/ChangeLog
index c2468c8..175bcaf 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,35 @@
+2018-03-16  Samuel Thibault  <samuel.thibault@ens-lyon.org>
+
+	* sysdeps/generic/thread_state.h (MACHINE_NEW_THREAD_STATE_FLAVOR):
+	Define macro.
+	* sysdeps/mach/thread_state.h (MACHINE_THREAD_STATE_FIX_NEW): New macro.
+	* sysdeps/mach/i386/thread_state.h
+	(MACHINE_NEW_THREAD_STATE_FLAVOR): New macro, defined to
+	i386_THREAD_STATE.
+	(MACHINE_THREAD_STATE_FLAVOR): Define to i386_REGS_SEGS_STATE instead of
+	i386_THREAD_STATE.
+	(MACHINE_THREAD_STATE_FIX_NEW): New macro, reads segments.
+
+	* sysdeps/mach/hurd/i386/trampoline.c (_hurd_setup_sighandler): Use
+	i386_REGS_SEGS_STATE instead of i386_THREAD_STATE.
+
+	* sysdeps/mach/hurd/i386/tls.h (TCB_ALIGNMENT, HURD_SEL_LDT): New
+	macros.
+	(_hurd_tls_fork): Add original thread parameter, Duplicate existing LDT
+	descriptor instead of creating a new one.
+	(_hurd_tls_new): New function, creates a new descriptor and updates tcb.
+
+	* mach/setup-thread.c: Include <ldsodefs.h>.
+	(__mach_setup_thread): Call _dl_allocate_tls, pass
+	MACHINE_NEW_THREAD_STATE_FLAVOR to __thread_set_state instead of
+	MACHINE_THREAD_STATE_FLAVOR, before getting
+	MACHINE_THREAD_STATE_FLAVOR, calling _hurd_tls_new, and setting
+	MACHINE_THREAD_STATE_FLAVOR with the result.
+	* hurd/hurdfault.c (_hurdsig_fault_init): Call
+	MACHINE_THREAD_STATE_FIX_NEW.
+	* sysdeps/mach/hurd/fork.c (__fork): Call _hurd_tls_fork for sigthread
+	too.  Add original thread parameter.
+
 2018-03-16  Joseph Myers  <joseph@codesourcery.com>
 
 	* sysdeps/x86/fpu/bits/mathinline.h [__USE_MISC] (__finite):
diff --git a/hurd/hurdfault.c b/hurd/hurdfault.c
index b5a4056..39a4522 100644
--- a/hurd/hurdfault.c
+++ b/hurd/hurdfault.c
@@ -204,6 +204,7 @@ _hurdsig_fault_init (void)
   /* This state will be restored when we fault.
      It runs the function above.  */
   memset (&state, 0, sizeof state);
+  MACHINE_THREAD_STATE_FIX_NEW (&state);
   MACHINE_THREAD_STATE_SET_PC (&state, faulted);
   MACHINE_THREAD_STATE_SET_SP (&state, faultstack, sizeof faultstack);
 
diff --git a/mach/setup-thread.c b/mach/setup-thread.c
index 2eeacc2..6716813 100644
--- a/mach/setup-thread.c
+++ b/mach/setup-thread.c
@@ -19,6 +19,7 @@
 #include <thread_state.h>
 #include <string.h>
 #include <mach/machine/vm_param.h>
+#include <ldsodefs.h>
 #include "sysdep.h"		/* Defines stack direction.  */
 
 #define	STACK_SIZE	(16 * 1024 * 1024) /* 16MB, arbitrary.  */
@@ -41,6 +42,7 @@ __mach_setup_thread (task_t task, thread_t thread, void *pc,
   vm_address_t stack;
   vm_size_t size;
   int anywhere;
+  tcbhead_t *tcb;
 
   size = stack_size ? *stack_size ? : STACK_SIZE : STACK_SIZE;
   stack = stack_base ? *stack_base ? : 0 : 0;
@@ -50,6 +52,10 @@ __mach_setup_thread (task_t task, thread_t thread, void *pc,
   if (error)
     return error;
 
+  tcb = _dl_allocate_tls(NULL);
+  if (tcb == NULL)
+    return KERN_RESOURCE_SHORTAGE;
+
   if (stack_size)
     *stack_size = size;
 
@@ -72,8 +78,21 @@ __mach_setup_thread (task_t task, thread_t thread, void *pc,
   if (error = __vm_protect (task, stack, __vm_page_size, 0, VM_PROT_NONE))
     return error;
 
-  return __thread_set_state (thread, MACHINE_THREAD_STATE_FLAVOR,
-			     (natural_t *) &ts, tssize);
+  if (error = __thread_set_state (thread, MACHINE_NEW_THREAD_STATE_FLAVOR,
+			     (natural_t *) &ts, tssize))
+    return error;
+
+  if (error = __thread_get_state (thread, MACHINE_THREAD_STATE_FLAVOR,
+			     (natural_t *) &ts, &tssize))
+    return error;
+  assert (tssize == MACHINE_THREAD_STATE_COUNT);
+
+  _hurd_tls_new(thread, &ts, tcb);
+
+  error = __thread_set_state (thread, MACHINE_THREAD_STATE_FLAVOR,
+			      (natural_t *) &ts, tssize);
+
+  return error;
 }
 
 weak_alias (__mach_setup_thread, mach_setup_thread)
diff --git a/sysdeps/generic/thread_state.h b/sysdeps/generic/thread_state.h
index 32994c3..99b7c92 100644
--- a/sysdeps/generic/thread_state.h
+++ b/sysdeps/generic/thread_state.h
@@ -22,6 +22,11 @@
 
 /* Replace <machine> with "i386" or "mips" or whatever.  */
 
+/* This lets the kernel define architecture-specific registers for a new
+   thread.  */
+#define MACHINE_NEW_THREAD_STATE_FLAVOR	<machine>_NEW_THREAD_STATE
+/* This makes the kernel load all architectures-specific registers for the
+   thread.  */
 #define MACHINE_THREAD_STATE_FLAVOR	<machine>_THREAD_STATE
 #define MACHINE_THREAD_STATE_COUNT	<machine>_THREAD_STATE_COUNT
 
diff --git a/sysdeps/mach/hurd/fork.c b/sysdeps/mach/hurd/fork.c
index b55eecf..cc322eb 100644
--- a/sysdeps/mach/hurd/fork.c
+++ b/sysdeps/mach/hurd/fork.c
@@ -507,6 +507,11 @@ __fork (void)
 #endif
       MACHINE_THREAD_STATE_SET_PC (&state,
 				   (unsigned long int) _hurd_msgport_receive);
+
+      /* Do special signal thread setup for TLS if needed.  */
+      if (err = _hurd_tls_fork (sigthread, _hurd_msgport_thread, &state))
+	LOSE;
+
       if (err = __thread_set_state (sigthread, MACHINE_THREAD_STATE_FLAVOR,
 				    (natural_t *) &state, statecount))
 	LOSE;
@@ -517,7 +522,7 @@ __fork (void)
       _hurd_longjmp_thread_state (&state, env, 1);
 
       /* Do special thread setup for TLS if needed.  */
-      if (err = _hurd_tls_fork (thread, &state))
+      if (err = _hurd_tls_fork (thread, ss->thread, &state))
 	LOSE;
 
       if (err = __thread_set_state (thread, MACHINE_THREAD_STATE_FLAVOR,
diff --git a/sysdeps/mach/hurd/i386/tls.h b/sysdeps/mach/hurd/i386/tls.h
index b194a49..4c78685 100644
--- a/sysdeps/mach/hurd/i386/tls.h
+++ b/sysdeps/mach/hurd/i386/tls.h
@@ -52,6 +52,15 @@ typedef struct
 #define TLS_TCB_AT_TP	1
 #define TLS_DTV_AT_TP	0
 
+/* Alignment requirement for TCB.
+
+   Some processors such as Intel Atom pay a big penalty on every
+   access using a segment override if that segment's base is not
+   aligned to the size of a cache line.  (See Intel 64 and IA-32
+   Architectures Optimization Reference Manual, section 13.3.3.3,
+   "Segment Base".)  On such machines, a cache line is 64 bytes.  */
+#define TCB_ALIGNMENT		64
+
 #ifndef __ASSEMBLER__
 
 /* Use i386-specific RPCs to arrange that %gs segment register prefix
@@ -78,6 +87,7 @@ typedef struct
       | (((unsigned int) (tcb)) & 0xff000000) /* base 24..31 */		      \
     }
 
+# define HURD_SEL_LDT(sel) (__builtin_expect((sel) & 4, 0))
 
 static inline const char * __attribute__ ((unused))
 _hurd_tls_init (tcbhead_t *tcb)
@@ -141,9 +151,40 @@ _hurd_tls_init (tcbhead_t *tcb)
 
 # include <mach/machine/thread_status.h>
 
-/* Set up TLS in the new thread of a fork child, copying from our own.  */
-static inline error_t __attribute__ ((unused))
-_hurd_tls_fork (thread_t child, struct i386_thread_state *state)
+/* Set up TLS in the new thread of a fork child, copying from the original.  */
+static inline kern_return_t __attribute__ ((unused))
+_hurd_tls_fork (thread_t child, thread_t orig, struct i386_thread_state *state)
+{
+  /* Fetch the selector set by _hurd_tls_init.  */
+  int sel;
+  asm ("mov %%gs, %w0" : "=q" (sel) : "0" (0));
+  if (sel == state->ds)		/* _hurd_tls_init was never called.  */
+    return 0;
+
+  struct descriptor desc, *_desc = &desc;
+  error_t err;
+  unsigned int count = 1;
+
+  if (HURD_SEL_LDT(sel))
+    err = __i386_get_ldt (orig, sel, 1, &_desc, &count);
+  else
+    err = __i386_get_gdt (orig, sel, &desc);
+
+  assert_perror (err);
+  if (err)
+    return err;
+
+  if (HURD_SEL_LDT(sel))
+    err = __i386_set_ldt (child, sel, &desc, 1);
+  else
+    err = __i386_set_gdt (child, &sel, desc);
+
+  state->gs = sel;
+  return err;
+}
+
+static inline kern_return_t __attribute__ ((unused))
+_hurd_tls_new (thread_t child, struct i386_thread_state *state, tcbhead_t *tcb)
 {
   /* Fetch the selector set by _hurd_tls_init.  */
   int sel;
@@ -151,11 +192,13 @@ _hurd_tls_fork (thread_t child, struct i386_thread_state *state)
   if (sel == state->ds)		/* _hurd_tls_init was never called.  */
     return 0;
 
-  tcbhead_t *const tcb = THREAD_SELF;
   HURD_TLS_DESC_DECL (desc, tcb);
   error_t err;
 
-  if (__builtin_expect (sel, 0x50) & 4) /* LDT selector */
+  tcb->tcb = tcb;
+  tcb->self = child;
+
+  if (HURD_SEL_LDT(sel))
     err = __i386_set_ldt (child, sel, &desc, 1);
   else
     err = __i386_set_gdt (child, &sel, desc);
diff --git a/sysdeps/mach/hurd/i386/trampoline.c b/sysdeps/mach/hurd/i386/trampoline.c
index d240ca7..0c68759 100644
--- a/sysdeps/mach/hurd/i386/trampoline.c
+++ b/sysdeps/mach/hurd/i386/trampoline.c
@@ -62,7 +62,7 @@ _hurd_setup_sighandler (struct hurd_sigstate *ss, __sighandler_t handler,
 		  sizeof (state->basic));
 	  memcpy (&state->fpu, &ss->context->sc_i386_float_state,
 		  sizeof (state->fpu));
-	  state->set |= (1 << i386_THREAD_STATE) | (1 << i386_FLOAT_STATE);
+	  state->set |= (1 << i386_REGS_SEGS_STATE) | (1 << i386_FLOAT_STATE);
 	}
     }
 
diff --git a/sysdeps/mach/i386/thread_state.h b/sysdeps/mach/i386/thread_state.h
index 56d91df..be3c8a9 100644
--- a/sysdeps/mach/i386/thread_state.h
+++ b/sysdeps/mach/i386/thread_state.h
@@ -21,7 +21,10 @@
 
 #include <mach/machine/thread_status.h>
 
-#define MACHINE_THREAD_STATE_FLAVOR	i386_THREAD_STATE
+/* This lets the kernel define segments for a new thread.  */
+#define MACHINE_NEW_THREAD_STATE_FLAVOR	i386_THREAD_STATE
+/* This makes the kernel load our segments descriptors.  */
+#define MACHINE_THREAD_STATE_FLAVOR	i386_REGS_SEGS_STATE
 #define MACHINE_THREAD_STATE_COUNT	i386_THREAD_STATE_COUNT
 
 #define machine_thread_state i386_thread_state
@@ -30,6 +33,14 @@
 #define SP uesp
 #define SYSRETURN eax
 
+#define MACHINE_THREAD_STATE_FIX_NEW(ts) do { \
+	asm ("mov %%cs, %w0" : "=q" ((ts)->cs)); \
+	asm ("mov %%ds, %w0" : "=q" ((ts)->ds)); \
+	asm ("mov %%es, %w0" : "=q" ((ts)->es)); \
+	asm ("mov %%fs, %w0" : "=q" ((ts)->fs)); \
+	asm ("mov %%gs, %w0" : "=q" ((ts)->gs)); \
+} while(0)
+
 struct machine_thread_all_state
   {
     int set;			/* Mask of bits (1 << FLAVOR).  */
diff --git a/sysdeps/mach/thread_state.h b/sysdeps/mach/thread_state.h
index bc4feef..2e3a10c 100644
--- a/sysdeps/mach/thread_state.h
+++ b/sysdeps/mach/thread_state.h
@@ -38,6 +38,12 @@
 #endif
 #endif
 
+/* This copies architecture-specific bits from the current thread to the new
+   thread state.  */
+#ifndef MACHINE_THREAD_STATE_FIX_NEW
+# define MACHINE_THREAD_STATE_FIX_NEW(ts)
+#endif
+
 /* These functions are of use in machine-dependent signal trampoline
    implementations.  */
 

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog                           |   32 +++++++++++++++++++++
 hurd/hurdfault.c                    |    1 +
 mach/setup-thread.c                 |   23 ++++++++++++++-
 sysdeps/generic/thread_state.h      |    5 +++
 sysdeps/mach/hurd/fork.c            |    7 ++++-
 sysdeps/mach/hurd/i386/tls.h        |   53 +++++++++++++++++++++++++++++++---
 sysdeps/mach/hurd/i386/trampoline.c |    2 +-
 sysdeps/mach/i386/thread_state.h    |   13 ++++++++-
 sysdeps/mach/thread_state.h         |    6 ++++
 9 files changed, 132 insertions(+), 10 deletions(-)


hooks/post-receive
-- 
GNU C Library master sources


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]