Index: arch/amd64/include/cpu.h
===================================================================
--- arch/amd64/include/cpu.h	(revision 9aa72b42058acb9ec55cd96d960e524465201dc6)
+++ arch/amd64/include/cpu.h	(revision 281b60742b0de3de113380f53c4ae400665518cf)
@@ -43,4 +43,5 @@
 #define AMD_MSR_LSTAR   0xc0000082
 #define AMD_MSR_SFMASK  0xc0000084
+#define AMD_MSR_FS      0xc0000100
 #define AMD_MSR_GS      0xc0000101
 
Index: arch/amd64/include/thread.h
===================================================================
--- arch/amd64/include/thread.h	(revision 9aa72b42058acb9ec55cd96d960e524465201dc6)
+++ arch/amd64/include/thread.h	(revision 281b60742b0de3de113380f53c4ae400665518cf)
@@ -30,5 +30,5 @@
 #define __amd64_THREAD_H__
 
-#define ARCH_THREAD_DATA
+#define ARCH_THREAD_DATA __native tls;
 
 #endif
Index: arch/amd64/src/amd64.c
===================================================================
--- arch/amd64/src/amd64.c	(revision 9aa72b42058acb9ec55cd96d960e524465201dc6)
+++ arch/amd64/src/amd64.c	(revision 281b60742b0de3de113380f53c4ae400665518cf)
@@ -33,4 +33,5 @@
 #include <config.h>
 
+#include <proc/thread.h>
 #include <arch/ega.h>
 #include <genarch/i8042/i8042.h>
@@ -48,4 +49,6 @@
 #include <arch/syscall.h>
 #include <arch/debugger.h>
+#include <syscall/syscall.h>
+
 
 /** Disable I/O on non-privileged levels
@@ -160,2 +163,17 @@
 	i8254_normal_operation();
 }
+
+/** Set Thread-local-storeage pointer
+ *
+ * TLS pointer is set in FS register. Unfortunately the 64-bit
+ * part can be set only in CPL0 mode.
+ *
+ * The specs says, that on %fs:0 there is stored contents of %fs register,
+ * we need not to go to CPL0 to read it.
+ */
+__native sys_tls_set(__native addr)
+{
+	THREAD->tls = addr;
+	write_msr(AMD_MSR_FS, addr);
+	return 0;
+}
Index: arch/amd64/src/proc/scheduler.c
===================================================================
--- arch/amd64/src/proc/scheduler.c	(revision 9aa72b42058acb9ec55cd96d960e524465201dc6)
+++ arch/amd64/src/proc/scheduler.c	(revision 281b60742b0de3de113380f53c4ae400665518cf)
@@ -46,4 +46,7 @@
 	swapgs();
 
+	/* TLS support - set FS to thread local storage */
+	write_msr(AMD_MSR_FS, THREAD->tls);
+
 #ifdef CONFIG_DEBUG_AS_WATCHPOINT
 	/* Set watchpoint on AS to ensure that nobody sets it to zero */
Index: arch/ia32/include/pm.h
===================================================================
--- arch/ia32/include/pm.h	(revision 9aa72b42058acb9ec55cd96d960e524465201dc6)
+++ arch/ia32/include/pm.h	(revision 281b60742b0de3de113380f53c4ae400665518cf)
@@ -31,5 +31,5 @@
 
 #define IDT_ITEMS 64
-#define GDT_ITEMS 6
+#define GDT_ITEMS 7
 
 #define NULL_DES	0
@@ -39,4 +39,5 @@
 #define UDATA_DES	4
 #define TSS_DES		5
+#define TLS_DES         6 /* Pointer to Thread-Local-Storage data */
 
 #define selector(des)	((des)<<3)
@@ -147,4 +148,5 @@
 
 extern void tss_initialize(struct tss *t);
+extern void set_tls_desc(__address tls);
 
 #endif /* __ASM__ */
Index: arch/ia32/include/thread.h
===================================================================
--- arch/ia32/include/thread.h	(revision 9aa72b42058acb9ec55cd96d960e524465201dc6)
+++ arch/ia32/include/thread.h	(revision 281b60742b0de3de113380f53c4ae400665518cf)
@@ -30,5 +30,5 @@
 #define __ia32_THREAD_H__
 
-#define ARCH_THREAD_DATA
+#define ARCH_THREAD_DATA __native tls;
 
 #endif
Index: arch/ia32/src/ia32.c
===================================================================
--- arch/ia32/src/ia32.c	(revision 9aa72b42058acb9ec55cd96d960e524465201dc6)
+++ arch/ia32/src/ia32.c	(revision 281b60742b0de3de113380f53c4ae400665518cf)
@@ -52,4 +52,6 @@
 #include <interrupt.h>
 #include <arch/debugger.h>
+#include <proc/thread.h>
+#include <syscall/syscall.h>
 
 void arch_pre_mm_init(void)
@@ -107,2 +109,18 @@
 	}
 }
+
+/** Set Thread-local-storeage pointer
+ *
+ * TLS pointer is set in FS register. Unfortunately the 64-bit
+ * part can be set only in CPL0 mode.
+ *
+ * The specs says, that on %fs:0 there is stored contents of %fs register,
+ * we need not to go to CPL0 to read it.
+ */
+__native sys_tls_set(__native addr)
+{
+	THREAD->tls = addr;
+	set_tls_desc(addr);
+
+	return 0;
+}
Index: arch/ia32/src/pm.c
===================================================================
--- arch/ia32/src/pm.c	(revision 9aa72b42058acb9ec55cd96d960e524465201dc6)
+++ arch/ia32/src/pm.c	(revision 281b60742b0de3de113380f53c4ae400665518cf)
@@ -49,4 +49,7 @@
  * mode, we use, for each privilege level, two segments spanning the
  * whole memory. One is for code and one is for data.
+ *
+ * One is for GS register which holds pointer to the TLS thread
+ * structure in it's base.
  */
 struct descriptor gdt[GDT_ITEMS] = {
@@ -62,5 +65,6 @@
 	{ 0xffff, 0, 0, AR_PRESENT | AR_DATA | AR_WRITABLE | DPL_USER, 0xf, 0, 0, 1, 1, 0 },
 	/* TSS descriptor - set up will be completed later */
-	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+	{ 0xffff, 0, 0, AR_PRESENT | AR_DATA | AR_WRITABLE | DPL_USER, 0xf, 0, 0, 1, 1, 0 }
 };
 
@@ -215,2 +219,14 @@
 	clean_AM_flag();          /* Disable alignment check */
 }
+
+void set_tls_desc(__address tls)
+{
+	struct ptr_16_32 cpugdtr;
+	struct descriptor *gdt_p = (struct descriptor *) cpugdtr.base;
+
+	__asm__ volatile ("sgdt %0\n" : : "m" (cpugdtr));
+
+	gdt_setbase(&gdt_p[TLS_DES], tls);
+	/* Reload gdt register to update GS in CPU */
+	__asm__ volatile ("lgdt %0\n" : : "m" (cpugdtr));
+}
Index: arch/ia32/src/proc/scheduler.c
===================================================================
--- arch/ia32/src/proc/scheduler.c	(revision 9aa72b42058acb9ec55cd96d960e524465201dc6)
+++ arch/ia32/src/proc/scheduler.c	(revision 281b60742b0de3de113380f53c4ae400665518cf)
@@ -33,4 +33,5 @@
 #include <arch/context.h>	/* SP_DELTA */
 #include <arch/debugger.h>
+#include <arch/pm.h>
 
 void before_thread_runs_arch(void)
@@ -38,4 +39,7 @@
 	CPU->arch.tss->esp0 = (__address) &THREAD->kstack[THREAD_STACK_SIZE-SP_DELTA];
 	CPU->arch.tss->ss0 = selector(KDATA_DES);
+
+	/* Set up TLS in GS register */
+	set_tls_desc(THREAD->tls);
 
 #ifdef CONFIG_DEBUG_AS_WATCHPOINT
Index: arch/ia32/src/userspace.c
===================================================================
--- arch/ia32/src/userspace.c	(revision 9aa72b42058acb9ec55cd96d960e524465201dc6)
+++ arch/ia32/src/userspace.c	(revision 281b60742b0de3de113380f53c4ae400665518cf)
@@ -56,4 +56,7 @@
 		"popfl\n"
 
+		/* Set up GS register (TLS) */
+		"movl %6, %%gs\n"
+
 		"pushl %0\n"
 		"pushl %1\n"
@@ -66,5 +69,6 @@
 		: "i" (selector(UDATA_DES) | PL_USER), "r" (kernel_uarg->uspace_stack+THREAD_STACK_SIZE),
 		  "r" (ipl), "i" (selector(UTEXT_DES) | PL_USER), "r" (kernel_uarg->uspace_entry),
-		  "r" (kernel_uarg->uspace_uarg)
+		"r" (kernel_uarg->uspace_uarg),
+		"r" (selector(TLS_DES))
 		: "eax");
 	
Index: arch/mips32/src/mips32.c
===================================================================
--- arch/mips32/src/mips32.c	(revision 9aa72b42058acb9ec55cd96d960e524465201dc6)
+++ arch/mips32/src/mips32.c	(revision 281b60742b0de3de113380f53c4ae400665518cf)
@@ -40,4 +40,5 @@
 #include <proc/uarg.h>
 #include <print.h>
+#include <syscall/syscall.h>
 
 #include <arch/interrupt.h>
@@ -142,2 +143,12 @@
 {
 }
+
+/** Set Thread-local-storeage pointer
+ *
+ * We have it currently in K1, it is
+ * possible to have it separately in the future.
+ */
+__native sys_tls_set(__native addr)
+{
+	return 0;
+}
Index: generic/include/syscall/syscall.h
===================================================================
--- generic/include/syscall/syscall.h	(revision 9aa72b42058acb9ec55cd96d960e524465201dc6)
+++ generic/include/syscall/syscall.h	(revision 281b60742b0de3de113380f53c4ae400665518cf)
@@ -32,4 +32,5 @@
 typedef enum {
 	SYS_IO = 0,
+	SYS_TLS_SET = 1, /* Hardcoded in AMD64,IA32 uspace - psthread.S */
 	SYS_THREAD_CREATE,
 	SYS_THREAD_EXIT,
@@ -60,4 +61,6 @@
 extern __native syscall_handler(__native a1, __native a2, __native a3,
 				__native a4, __native id);
+extern __native sys_tls_set(__native addr);
+
 
 #endif
Index: generic/src/syscall/syscall.c
===================================================================
--- generic/src/syscall/syscall.c	(revision 9aa72b42058acb9ec55cd96d960e524465201dc6)
+++ generic/src/syscall/syscall.c	(revision 281b60742b0de3de113380f53c4ae400665518cf)
@@ -76,4 +76,5 @@
 syshandler_t syscall_table[SYSCALL_END] = {
 	sys_io,
+	sys_tls_set,
 	sys_thread_create,
 	sys_thread_exit,
