Samuel Thibault, le Mon 25 Jun 2007 01:24:41 +0200, a écrit :
> Samuel Thibault, le Sun 24 Jun 2007 21:29:50 +0200, a écrit :
> > Samuel Thibault, le Sun 24 Jun 2007 17:51:25 +0200, a écrit :
> > > I've uploaded some experimental TLS-enabled hurd and libc packages for
> > > testing to
> > > 
> > > http://dept-info.labri.fr/~thibault/debian-hurd/tls/
> > 
> > They need the gdt user_ldt.c update, so make sure to have gnumach >=
> > 20070405.
> 
> Note: though it works nicely on my box (I'm compiling glibc HEAD with it
> right now), it looks like it fails completely on others (Thomas and
> Olaf's at least), so please be careful :)

The problem I was having with Xen was when switch_ktss changes() the
descriptors, because in an interrupt context, gs is still loaded with
the user-level value. In january 2006, Jeroen made trap handlers load
kernel data segments in fs and gs, here is a patch to do the same on
interrupts (with it, I don't have issues on Xen any more).

Could people try TLS with a patched gnumach?

Note: there is still an issue with mach-defpager.

Samuel
Index: i386/i386/db_interface.c
===================================================================
RCS file: /cvsroot/hurd/gnumach/i386/i386/Attic/db_interface.c,v
retrieving revision 1.2.2.3.2.1
diff -u -p -r1.2.2.3.2.1 db_interface.c
--- i386/i386/db_interface.c    7 Jul 2007 17:21:19 -0000       1.2.2.3.2.1
+++ i386/i386/db_interface.c    8 Jul 2007 21:30:21 -0000
@@ -187,8 +187,6 @@ kdb_trap(
  *     instead of those at its call to KDB.
  */
 struct int_regs {
-       int     gs;
-       int     fs;
        int     edi;
        int     esi;
        int     ebp;
@@ -227,8 +225,8 @@ kdb_kentry(
            ddb_regs.edi = int_regs->edi;
            ddb_regs.ds  = is->ds;
            ddb_regs.es  = is->es;
-           ddb_regs.fs  = int_regs->fs;
-           ddb_regs.gs  = int_regs->gs;
+           ddb_regs.fs  = is->fs;
+           ddb_regs.gs  = is->gs;
 
            cnpollc(TRUE);
            db_task_trap(-1, 0, (ddb_regs.cs & 0x3) != 0);
@@ -250,8 +248,8 @@ kdb_kentry(
            int_regs->edi = ddb_regs.edi;
            is->ds  = ddb_regs.ds & 0xffff;
            is->es  = ddb_regs.es & 0xffff;
-           int_regs->fs = ddb_regs.fs & 0xffff;
-           int_regs->gs = ddb_regs.gs & 0xffff;
+           is->fs  = ddb_regs.fs & 0xffff;
+           is->gs  = ddb_regs.gs & 0xffff;
        }
 #if    NCPUS > 1
        db_leave();
Index: i386/i386/kttd_interface.c
===================================================================
RCS file: /cvsroot/hurd/gnumach/i386/i386/Attic/kttd_interface.c,v
retrieving revision 1.2.2.3.2.1
diff -u -p -r1.2.2.3.2.1 kttd_interface.c
--- i386/i386/kttd_interface.c  7 Jul 2007 17:21:19 -0000       1.2.2.3.2.1
+++ i386/i386/kttd_interface.c  8 Jul 2007 21:30:21 -0000
@@ -491,8 +491,6 @@ boolean_t kttd_trap(int     type, int code, 
  *     instead of those at its call to KDB.
  */
 struct int_regs {
-       int     gs;
-       int     fs;
        int     edi;
        int     esi;
        int     ebp;
@@ -541,8 +539,8 @@ kttd_netentry(int_regs)
        kttd_regs.edi = int_regs->edi;
        kttd_regs.ds  = is->ds;
        kttd_regs.es  = is->es;
-       kttd_regs.fs  = int_regs->fs;
-       kttd_regs.gs  = int_regs->gs;
+       kttd_regs.fs  = is->fs;
+       kttd_regs.gs  = is->gs;
 
        kttd_active++;
        kttd_task_trap(-1, 0, (kttd_regs.cs & 0x3) != 0);
@@ -564,8 +562,8 @@ kttd_netentry(int_regs)
        int_regs->edi = kttd_regs.edi;
        is->ds  = kttd_regs.ds & 0xffff;
        is->es  = kttd_regs.es & 0xffff;
-       int_regs->fs = kttd_regs.fs & 0xffff;
-       int_regs->gs = kttd_regs.gs & 0xffff;
+       is->fs  = kttd_regs.fs & 0xffff;
+       is->gs  = kttd_regs.gs & 0xffff;
 
        if (kttd_run_status == RUNNING)
                printf("kttd_netentry: %%%%% run_status already RUNNING! 
%%%%%\n");
Index: i386/i386/locore.S
===================================================================
RCS file: /cvsroot/hurd/gnumach/i386/i386/locore.S,v
retrieving revision 1.6.2.7.2.3
diff -u -p -r1.6.2.7.2.3 locore.S
--- i386/i386/locore.S  7 May 2007 22:54:50 -0000       1.6.2.7.2.3
+++ i386/i386/locore.S  8 Jul 2007 21:30:21 -0000
@@ -646,9 +646,13 @@ ENTRY(all_intrs)
 
        pushl   %ds                     /* save segment registers */
        pushl   %es
+       pushl   %fs
+       pushl   %gs
        mov     %ss,%dx                 /* switch to kernel segments */
        mov     %dx,%ds
        mov     %dx,%es
+       mov     %dx,%fs
+       mov     %dx,%gs
 
        CPU_NUMBER(%edx)
 
@@ -686,7 +690,9 @@ LEXT(return_to_iret)                        /* ( label for 
kd
        cmpl    $0,CX(EXT(need_ast),%edx)
        jnz     ast_from_interrupt      /* take it if so */
 1:
-       pop     %es                     /* restore segment regs */
+       pop     %gs                     /* restore segment regs */
+       pop     %fs
+       pop     %es
        pop     %ds
        pop     %edx
        pop     %ecx
@@ -704,11 +710,13 @@ _return_to_iret_i:                        /* ( label for 
kdb_
 /*
  *     Take an AST from an interrupt.
  *     On PCB stack.
- * sp->        es      -> edx
- *     ds      -> ecx
- *     edx     -> eax
- *     ecx     -> trapno
- *     eax     -> code
+ * sp->        gs      -> edx
+ *     fs      -> ecx
+ *     es      -> eax
+ *     ds      -> trapno
+ *     edx     -> code
+ *     ecx
+ *     eax
  *     eip
  *     cs
  *     efl
@@ -716,7 +724,9 @@ _return_to_iret_i:                  /* ( label for kdb_
  *     ss
  */
 ast_from_interrupt:
-       pop     %es                     /* restore all registers ... */
+       pop     %gs                     /* restore all registers ... */
+       pop     %fs
+       pop     %es
        pop     %ds
        popl    %edx
        popl    %ecx
@@ -731,6 +741,8 @@ ast_from_interrupt:
        mov     %ss,%dx                 /* switch to kernel segments */
        mov     %dx,%ds
        mov     %dx,%es
+       mov     %dx,%fs
+       mov     %dx,%gs
 
        CPU_NUMBER(%edx)
        TIME_TRAP_UENTRY
@@ -768,7 +780,9 @@ ast_from_interrupt:
  *             pointer to save area on old stack
  *           [ saved %ebx, if accurate timing ]
  *
- * old stack:  saved %es
+ * old stack:  saved %gs
+ *             saved %fs
+ *             saved %es
  *             saved %ds
  *             saved %edx
  *             saved %ecx
@@ -820,14 +834,10 @@ kdb_from_iret:
        pushl   %ebp
        pushl   %esi
        pushl   %edi
-       push    %fs
-       push    %gs
        pushl   %esp                    /* pass regs */
        call    EXT(kdb_kentry)         /* to kdb */
        addl    $4,%esp                 /* pop parameters */
-       pop     %gs                     /* restore registers */
-       pop     %fs
-       popl    %edi
+       popl    %edi                    /* restore registers */
        popl    %esi
        popl    %ebp
 #if    STAT_TIME
@@ -906,14 +916,10 @@ ttd_from_iret:
        pushl   %ebp
        pushl   %esi
        pushl   %edi
-       push    %fs
-       push    %gs
        pushl   %esp                    /* pass regs */
        call    _kttd_netentry          /* to kdb */
        addl    $4,%esp                 /* pop parameters */
-       pop     %gs                     /* restore registers */
-       pop     %fs
-       popl    %edi
+       popl    %edi                    /* restore registers */
        popl    %esi
        popl    %ebp
 #if    STAT_TIME
Index: i386/i386/thread.h
===================================================================
RCS file: /cvsroot/hurd/gnumach/i386/i386/thread.h,v
retrieving revision 1.3.2.1.2.1
diff -u -p -r1.3.2.1.2.1 thread.h
--- i386/i386/thread.h  7 May 2007 22:54:50 -0000       1.3.2.1.2.1
+++ i386/i386/thread.h  8 Jul 2007 21:30:21 -0000
@@ -139,6 +139,8 @@ struct v86_assist_state {
  */
 
 struct i386_interrupt_state {
+       int     gs;
+       int     fs;
        int     es;
        int     ds;
        int     edx;
Index: linux/src/include/asm-i386/irq.h
===================================================================
RCS file: /cvsroot/hurd/gnumach/linux/src/include/asm-i386/Attic/irq.h,v
retrieving revision 1.1
diff -u -p -r1.1 irq.h
--- linux/src/include/asm-i386/irq.h    26 Apr 1999 05:55:48 -0000      1.1
+++ linux/src/include/asm-i386/irq.h    8 Jul 2007 21:30:21 -0000
@@ -38,6 +38,7 @@ extern void enable_irq(unsigned int);
        "movl $" STR(KERNEL_DS) ",%edx\n\t" \
        "mov %dx,%ds\n\t" \
        "mov %dx,%es\n\t" \
+       "mov %dx,%gs\n\t" \
        "movl $" STR(USER_DS) ",%edx\n\t" \
        "mov %dx,%fs\n\t"   \
        "movl $0,%edx\n\t"  \

Reply via email to