A few weeks ago I was working on getting TLS working on the Hurd. Unfortunately, I don't have much time anymore to work further on it, so I share the bugfixes I already have. The patch below fixes gnumach's LDT code, so we can use the gs segment register for TLS.
The first part of the patch makes sure the fs and gs registers are correct when entering kernel mode. This needs to be done because when running in kernel mode we use the kernel LDT and the fs/gs registers point to segment descriptors in the user LDT if we created our own segments. The second part of the patch makes sure we always copy the master LDT from the kernel when there doesn't exist a modified LDT for the user yet. If we don't do this, we don't have any segment descriptors for the cs and ds segments when switching to the new LDT. With this patch I didn't experience any gnumach crashes anymore when working on TLS. Jeroen Dekkers 2005-09-18 Jeroen Dekkers <[EMAIL PROTECTED]> * i386/i386/locore.S (trap_push_segs): Switch fs and gs to kernel data segment too. (syscall_entry_2): Likewise. * i386/i386/user_ldt.c (i386_set_ldt): Always copy the master LDT when there is no old user LDT. Index: i386/i386/locore.S =================================================================== RCS file: /cvsroot/hurd/gnumach/i386/i386/locore.S,v retrieving revision 1.6.2.1 diff -u -p -r1.6.2.1 locore.S --- i386/i386/locore.S 28 Nov 2004 17:29:35 -0000 1.6.2.1 +++ i386/i386/locore.S 30 Aug 2005 10:34:02 -0000 @@ -464,6 +464,8 @@ trap_push_segs: mov %ss,%ax /* switch to kernel data segment */ mov %ax,%ds /* (same as kernel stack segment) */ mov %ax,%es + mov %ax,%fs + mov %ax,%gs trap_set_segs: cld /* clear direction flag */ @@ -982,6 +984,8 @@ syscall_entry_2: mov %ss,%dx /* switch to kernel data segment */ mov %dx,%ds mov %dx,%es + mov %dx,%fs + mov %dx,%gs /* * Shuffle eflags,eip,cs into proper places Index: i386/i386/user_ldt.c =================================================================== RCS file: /cvsroot/hurd/gnumach/i386/i386/user_ldt.c,v retrieving revision 1.2 diff -u -p -r1.2 user_ldt.c --- i386/i386/user_ldt.c 16 Sep 1999 02:17:48 -0000 1.2 +++ i386/i386/user_ldt.c 30 Aug 2005 10:34:02 -0000 @@ -225,7 +225,7 @@ i386_set_ldt(thread, first_selector, des (char *)&new_ldt->ldt[0], old_ldt->desc.limit_low + 1); } - else if (thread == current_thread()) { + else { struct real_descriptor template = {0, 0, 0, ACC_P, 0, 0 ,0}; for (dp = &new_ldt->ldt[0], i = 0; i < first_desc; i++, dp++) { _______________________________________________ Bug-hurd mailing list Bug-hurd@gnu.org http://lists.gnu.org/mailman/listinfo/bug-hurd