Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 23 Jun 2005 08:34:09 GMT
From:      Peter Wemm <peter@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 78852 for review
Message-ID:  <200506230834.j5N8Y90n016894@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=78852

Change 78852 by peter@peter_overcee on 2005/06/23 08:33:41

	Attempt to recover from the wrong gsbase state after a fault
	from doreti()::iretq.  Even though we're coming from kernel mode
	we have to swapgs and friends before enabling interrupts.
	XXX may need to move load_gs and load_fs from C to asm in order to
	do the magic there too.

Affected files ...

.. //depot/projects/hammer/sys/amd64/amd64/exception.S#38 edit

Differences ...

==== //depot/projects/hammer/sys/amd64/amd64/exception.S#38 (text+ko) ====

@@ -126,8 +126,6 @@
 	TRAP_ERR(T_SEGNPFLT)
 IDTVEC(stk)
 	TRAP_ERR(T_STKFLT)
-IDTVEC(prot)
-	TRAP_ERR(T_PROTFLT)
 IDTVEC(align)
 	TRAP_ERR(T_ALIGNFLT)
 
@@ -203,7 +201,8 @@
 	testb	$SEL_RPL_MASK,TF_CS(%rsp) /* Did we come from kernel? */
 	jz	1f			/* already running with kernel GS.base */
 	swapgs
-1:	movq	%rdi,TF_RDI(%rsp)	/* free up a GP register */
+1:
+	movq	%rdi,TF_RDI(%rsp)	/* free up a GP register */
 	movq	%cr2,%rdi		/* preserve %cr2 before ..  */
 	movq	%rdi,TF_ADDR(%rsp)	/* enabling interrupts. */
 	testl	$PSL_I,TF_RFLAGS(%rsp)
@@ -211,6 +210,30 @@
 	sti
 	jmp	alltraps_pushregs_no_rdi
 
+	/*
+	 * We have to special-case this one.  If we get a trap in doreti() at
+	 * the iretq stage, we'll reenter with the wrong gs state.  We'll have
+	 * to do a special the swapgs in this case even coming from the kernel.
+	 * XXX linux has a trap handler for their equivalent of load_gs().
+	 */
+IDTVEC(prot)
+	subq	$TF_ERR,%rsp
+	movq	$T_PROTFLT,TF_TRAPNO(%rsp)
+	movq	$0,TF_ADDR(%rsp)
+	movq	%rdi,TF_RDI(%rsp)	/* free up a GP register */
+	leaq	doreti_iret(%rip),%rdi
+	cmpq	%rdi,TF_RIP(%rsp)
+	je	2f			/* kernel but with user gsbase!! */
+	testb	$SEL_RPL_MASK,TF_CS(%rsp) /* Did we come from kernel? */
+	jz	1f			/* already running with kernel GS.base */
+2:
+	swapgs
+1:
+	testl	$PSL_I,TF_RFLAGS(%rsp)
+	jz	alltraps_pushregs_no_rdi
+	sti
+	jmp	alltraps_pushregs_no_rdi
+
 /*
  * Fast syscall entry point.  We enter here with just our new %cs/%ss set,
  * and the new privilige level.  We are still running on the old user stack



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200506230834.j5N8Y90n016894>