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

Re: please test TLS



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 to: