Index: c/src/lib/libbsp/i386/pc386/include/tblsizes.h
===================================================================
--- c/src/lib/libbsp/i386/pc386/include/tblsizes.h	(revision cb0d9a0747b1be84fb669b1c71e55bf0d860d2f8)
+++ c/src/lib/libbsp/i386/pc386/include/tblsizes.h	(revision 7b0c74ffb085656d67554102857224223ee03f88)
@@ -21,3 +21,4 @@
 
 #define IDT_SIZE (256)
-#define GDT_SIZE (3 + NUM_APP_DRV_GDT_DESCRIPTORS)
+#define NUM_SYSTEM_GDT_DESCRIPTORS 4
+#define GDT_SIZE (NUM_SYSTEM_GDT_DESCRIPTORS + NUM_APP_DRV_GDT_DESCRIPTORS)
Index: c/src/lib/libbsp/i386/pc386/startup/ldsegs.S
===================================================================
--- c/src/lib/libbsp/i386/pc386/startup/ldsegs.S	(revision cb0d9a0747b1be84fb669b1c71e55bf0d860d2f8)
+++ c/src/lib/libbsp/i386/pc386/startup/ldsegs.S	(revision 7b0c74ffb085656d67554102857224223ee03f88)
@@ -172,6 +172,6 @@
 | GDT itself
 +--------------------------------------------------------------------------*/
-#if GDT_SIZE < 3
-#error "GDT_SIZE must be at least 3"
+#if GDT_SIZE < NUM_SYSTEM_GDT_DESCRIPTORS
+#error "GDT_SIZE must be at least NUM_SYSTEM_GDT_DESCRIPTORS"
 #endif
 
@@ -194,6 +194,10 @@
 	.byte 0, 0x92, 0xcf, 0
 
+	/* gs segment */
+	.word 0xffff, 0
+	.byte 0, 0x92, 0xcf, 0
+
         /* allocated space for user segments */
-        .rept (GDT_SIZE - 3)
+        .rept (GDT_SIZE - NUM_SYSTEM_GDT_DESCRIPTORS)
         .word 0,0,0,0
         .endr
Index: c/src/lib/libbsp/i386/shared/irq/idt.c
===================================================================
--- c/src/lib/libbsp/i386/shared/irq/idt.c	(revision cb0d9a0747b1be84fb669b1c71e55bf0d860d2f8)
+++ c/src/lib/libbsp/i386/shared/irq/idt.c	(revision 7b0c74ffb085656d67554102857224223ee03f88)
@@ -19,4 +19,5 @@
 #include <rtems/score/cpu.h>
 #include <bsp/irq.h>
+#include <bsp/tblsizes.h>
 
 /*
@@ -332,5 +333,5 @@
     segment_descriptors*    gdt_entry_tbl;
     /* initial amount of filled descriptors */
-    static uint16_t         segment_selector_index = 2;
+    static uint16_t         segment_selector_index = NUM_SYSTEM_GDT_DESCRIPTORS - 1;
 
     segment_selector_index += 1;
Index: cpukit/score/cpu/i386/cpu.c
===================================================================
--- cpukit/score/cpu/i386/cpu.c	(revision cb0d9a0747b1be84fb669b1c71e55bf0d860d2f8)
+++ cpukit/score/cpu/i386/cpu.c	(revision 7b0c74ffb085656d67554102857224223ee03f88)
@@ -25,4 +25,5 @@
 #include <rtems/score/isr.h>
 #include <rtems/score/idtr.h>
+#include <rtems/score/tls.h>
 
 #include <rtems/bspIo.h>
@@ -43,4 +44,10 @@
 I386_ASSERT_OFFSET(esi, ESI);
 I386_ASSERT_OFFSET(edi, EDI);
+
+RTEMS_STATIC_ASSERT(
+  offsetof(Context_Control, gs)
+    == I386_CONTEXT_CONTROL_GS_0_OFFSET,
+  Context_Control_gs_0
+);
 
 #ifdef RTEMS_SMP
@@ -154,4 +161,5 @@
 {
   uint32_t _stack;
+  uint32_t tcb;
 
   (void) is_fp; /* avoid warning for being unused */
@@ -169,4 +177,21 @@
   the_context->ebp     = (void *) 0;
   the_context->esp     = (void *) _stack;
+
+  if ( tls_area != NULL ) {
+    tcb = (uint32_t) _TLS_TCB_after_TLS_block_initialize( tls_area );
+  } else {
+    tcb = 0;
+  }
+
+  the_context->gs.limit_15_0 = 0xffff;
+  the_context->gs.base_address_15_0 = (tcb >> 0) & 0xffff;
+  the_context->gs.type = 0x2;
+  the_context->gs.descriptor_type = 0x1;
+  the_context->gs.limit_19_16 = 0xf;
+  the_context->gs.present = 0x1;
+  the_context->gs.operation_size = 0x1;
+  the_context->gs.granularity = 0x1;
+  the_context->gs.base_address_23_16 = (tcb >> 16) & 0xff;
+  the_context->gs.base_address_31_24 = (tcb >> 24) & 0xff;
 }
 
Index: cpukit/score/cpu/i386/cpu_asm.S
===================================================================
--- cpukit/score/cpu/i386/cpu_asm.S	(revision cb0d9a0747b1be84fb669b1c71e55bf0d860d2f8)
+++ cpukit/score/cpu/i386/cpu_asm.S	(revision 7b0c74ffb085656d67554102857224223ee03f88)
@@ -33,4 +33,6 @@
 .set REG_ESI,     I386_CONTEXT_CONTROL_ESI_OFFSET
 .set REG_EDI,     I386_CONTEXT_CONTROL_EDI_OFFSET
+.set REG_GS_0,    I386_CONTEXT_CONTROL_GS_0_OFFSET
+.set REG_GS_1,    I386_CONTEXT_CONTROL_GS_1_OFFSET
 
         BEGIN_CODE
@@ -84,4 +86,10 @@
         movl      REG_ESI(eax),esi         /* restore source register */
         movl      REG_EDI(eax),edi         /* restore destination register */
+        movl      REG_GS_0(eax), ecx       /* restore gs segment */
+        movl      REG_GS_1(eax), edx
+        movl      ecx, _Global_descriptor_table + 24
+        movl      edx, _Global_descriptor_table + 28
+        movl      $24, ecx
+        mov       ecx, gs
         ret
 
Index: cpukit/score/cpu/i386/rtems/score/cpu.h
===================================================================
--- cpukit/score/cpu/i386/rtems/score/cpu.h	(revision cb0d9a0747b1be84fb669b1c71e55bf0d860d2f8)
+++ cpukit/score/cpu/i386/rtems/score/cpu.h	(revision 7b0c74ffb085656d67554102857224223ee03f88)
@@ -123,7 +123,9 @@
 #define I386_CONTEXT_CONTROL_ESI_OFFSET 16
 #define I386_CONTEXT_CONTROL_EDI_OFFSET 20
+#define I386_CONTEXT_CONTROL_GS_0_OFFSET 24
+#define I386_CONTEXT_CONTROL_GS_1_OFFSET 28
 
 #ifdef RTEMS_SMP
-  #define I386_CONTEXT_CONTROL_IS_EXECUTING_OFFSET 24
+  #define I386_CONTEXT_CONTROL_IS_EXECUTING_OFFSET 32
 #endif
 
@@ -137,10 +139,11 @@
 
 typedef struct {
-  uint32_t    eflags;   /* extended flags register                   */
-  void       *esp;      /* extended stack pointer register           */
-  void       *ebp;      /* extended base pointer register            */
-  uint32_t    ebx;      /* extended bx register                      */
-  uint32_t    esi;      /* extended source index register            */
-  uint32_t    edi;      /* extended destination index flags register */
+  uint32_t    eflags;     /* extended flags register                   */
+  void       *esp;        /* extended stack pointer register           */
+  void       *ebp;        /* extended base pointer register            */
+  uint32_t    ebx;        /* extended bx register                      */
+  uint32_t    esi;        /* extended source index register            */
+  uint32_t    edi;        /* extended destination index flags register */
+  segment_descriptors gs; /* gs segment descriptor                     */
 #ifdef RTEMS_SMP
   volatile bool is_executing;
Index: cpukit/score/include/rtems/score/tls.h
===================================================================
--- cpukit/score/include/rtems/score/tls.h	(revision cb0d9a0747b1be84fb669b1c71e55bf0d860d2f8)
+++ cpukit/score/include/rtems/score/tls.h	(revision 7b0c74ffb085656d67554102857224223ee03f88)
@@ -71,7 +71,11 @@
 } TLS_Dynamic_thread_vector;
 
-typedef struct {
+typedef struct TLS_Thread_control_block {
+#ifdef __i386__
+  struct TLS_Thread_control_block *tcb;
+#else
   TLS_Dynamic_thread_vector *dtv;
   uintptr_t reserved;
+#endif
 } TLS_Thread_control_block;
 
@@ -110,8 +114,14 @@
 )
 {
-  uintptr_t aligned_size = _TLS_Heap_align_up( size );
-
-  return _TLS_Get_thread_control_block_area_size( alignment )
-    + aligned_size + sizeof(TLS_Dynamic_thread_vector);
+  uintptr_t allocation_size = 0;
+
+  allocation_size += _TLS_Heap_align_up( size );
+  allocation_size += _TLS_Get_thread_control_block_area_size( alignment );
+
+#ifndef __i386__
+  allocation_size += sizeof(TLS_Dynamic_thread_vector);
+#endif
+
+  return allocation_size;
 }
 
@@ -141,7 +151,12 @@
 )
 {
+#ifdef __i386__
+  (void) dtv;
+  tcb->tcb = tcb;
+#else
   tcb->dtv = dtv;
   dtv->generation_number = 1;
   dtv->tls_blocks[0] = tls_block;
+#endif
 
   return _TLS_Copy_and_clear( tls_block );
