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

Re: Please test/upgrade to hurd_20070606-2



Michael Banck, le Thu 02 Aug 2007 15:41:21 +0200, a écrit :
> On Thu, Aug 02, 2007 at 03:16:53PM +0200, Michael Banck wrote:
> > On Thu, Aug 02, 2007 at 03:11:24PM +0200, Samuel Thibault wrote:
> > > Michael Banck, le Thu 02 Aug 2007 14:36:47 +0200, a écrit :
> > > > Actually, I thought about reverting to glibc-2.5 for the buildd again,
> > > > because I got a couple of GPF's all at
> > > > 
> > > > copyout_retry
> > > > ../i386/i386/locore.S:1261
> > > 
> > > i.e. movl %cr3,%ecx ?! I fail to see how this can trigger a GPF...
> > 
> > Yes, that one.  I got the same GPF four times now, no others so far.
> 
> Uh, ok, my bad.  It was a GPT:
> 
> "Kernel General protection trap, eip 0x101f8d
> kernel: General protection (13), code=50
> Stopped at 0x101f8d:  movl %cr3,%ecx"

Could you try with my previously-posted gnumach-gs patch, attached again
with this mail?  This looks to me like the same issue as I got with Xen:
the recovery mecanism restores a bogus gs value at a kernel level, which
makes the kernel panic.  With this patch, that should be user level that
gets the trap, hence a segfault.

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: