[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] Fix for gnumach's LDT code

From: Jeroen Dekkers
Subject: [PATCH] Fix for gnumach's LDT code
Date: Sun, 18 Sep 2005 15:27:46 +0200
User-agent: Wanderlust/2.14.0 (Africa) SEMI/1.14.6 (Maruoka) FLIM/1.14.7 (Sanjō) APEL/10.6 Emacs/22.0.50 (i486-pc-linux-gnu) MULE/5.0 (SAKAKI)

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

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  <jeroen@dekkers.cx>

        * 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
diff -u -p -r1.6.2.1 locore.S
--- i386/i386/locore.S  28 Nov 2004 17:29:35 -0000
+++ 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
        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++) {

reply via email to

[Prev in Thread] Current Thread [Next in Thread]