Subject: kernel: supervisor trap asynchronous system trap, code=0
To: None <port-xen@netbsd.org>
From: Manuel Bouyer <bouyer@antioche.eu.org>
List: port-xen
Date: 06/28/2007 00:18:44
--+HP7ph2BbKc20aGI
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Hi,
I've been working on the Xen interrupt code, especially to fix the places
where it reenable interrupts without checking for pending interrupts
(which could cause interrupts to be deffered until the next IRQ
or hypercall), see attached diff.

With this, I get a
kernel: supervisor trap asynchronous system trap, code=0
when running a HVM guest (it may not be related to the HVM code, it may just
be because of the high interrupt load).
The trap consistenly hapens in i386_copyin, on the loop copying the data,
called from syscall_plain() through the uvm and ffs code.
As I understand it, AST should only happen for user context, and here it
seems to occur in a kernel context. I'm not sure why this happens and
I can't see how my patch would change anything in this area (it can just
make a bug shows up more easily by calling the interrupt handlers more
agressively). Especially it doesn't add any movl $T_ASTFLT AFAIK.
Any idea ?

-- 
Manuel Bouyer <bouyer@antioche.eu.org>
     NetBSD: 26 ans d'experience feront toujours la difference
--

--+HP7ph2BbKc20aGI
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=diff

Index: i386/locore.S
===================================================================
RCS file: /cvsroot/src/sys/arch/xen/i386/locore.S,v
retrieving revision 1.25
diff -u -r1.25 locore.S
--- i386/locore.S	17 May 2007 14:51:35 -0000	1.25
+++ i386/locore.S	27 Jun 2007 21:59:37 -0000
@@ -663,6 +663,7 @@
 	 * Switch to newlwp's stack.
 	 */
 
+	CLI(%ebx)
 	movl	L_ADDR(%edi),%ebx
 	movl	PCB_EBP(%ebx),%ebp
 	movl	PCB_ESP(%ebx),%esp
@@ -680,6 +681,7 @@
 	addl	$4,%esp
 
 	movl	$0,CPUVAR(RESCHED)
+	STI(%ebx)
 
 	/*
 	 *  Check for restartable atomic sequences (RAS)
@@ -690,6 +692,16 @@
 	jne	check_ras
 
 switch_return:
+#if 0
+	STIC(%ebx)
+	jz 1f
+	call	_C_LABEL(stipending)
+	testl	%eax,%eax
+	jz 1f
+	pushl  CPUVAR(ILEVEL)
+	call	_C_LABEL(Xspllower) # process pending interrupts
+1:
+#endif
 	movl	%esi,%eax	# return 'oldlwp'
 	popl	%edi
 	popl	%esi
@@ -780,9 +792,29 @@
 	call	_C_LABEL(trap)
 	addl	$4,%esp
 	jmp	.Lsyscall_checkast
-1:	STI(%eax)
-	CHECK_DEFERRED_SWITCH(%eax)
+1:	CHECK_DEFERRED_SWITCH(%eax)
 	jnz	9f
+	STIC(%eax)
+	jz	14f
+	call	_C_LABEL(stipending)
+	testl	%eax,%eax
+	jz	14f
+	/* process pending interrupts */
+	CLI(%eax)
+	movl	CPUVAR(ILEVEL), %ebx
+	movl	$.Lsyscall_resume, %esi # address to resume loop at
+.Lsyscall_resume:
+	movl	%ebx,%eax		# get cpl
+	movl	CPUVAR(IUNMASK)(,%eax,4),%eax
+	andl	CPUVAR(IPENDING),%eax	# any non-masked bits left?
+	jz	17f
+	bsrl	%eax,%eax
+	btrl	%eax,CPUVAR(IPENDING)
+	movl	CPUVAR(ISOURCES)(,%eax,4),%eax
+	jmp	*IS_RESUME(%eax)
+17:	movl	%ebx, CPUVAR(ILEVEL)	#restore cpl
+	jmp	.Lsyscall_checkast
+14:
 #ifndef DIAGNOSTIC
 	INTRFASTEXIT
 #else /* DIAGNOSTIC */
@@ -801,7 +833,8 @@
 5:	.asciz	"WARNING: SPL NOT ZERO ON SYSCALL ENTRY\n"
 6:	.asciz	"WARNING: WANT PMAPLOAD ON SYSCALL ENTRY\n"
 #endif /* DIAGNOSTIC */
-9:	call    _C_LABEL(pmap_load)
+9:	STI(%eax)
+	call    _C_LABEL(pmap_load)
 	jmp     .Lsyscall_checkast        /* re-check ASTs */
 
 #if NNPX > 0
Index: i386/spl.S
===================================================================
RCS file: /cvsroot/src/sys/arch/xen/i386/spl.S,v
retrieving revision 1.9
diff -u -r1.9 spl.S
--- i386/spl.S	25 Jun 2007 20:09:34 -0000	1.9
+++ i386/spl.S	27 Jun 2007 21:59:37 -0000
@@ -144,8 +144,6 @@
  * called with interrupt disabled.
  */
 IDTVEC(doreti)
-	IDEPTH_DECR
-	popl	%ebx			# get previous priority
 .Ldoreti_resume:
 	movl	$.Ldoreti_resume,%esi	# address to resume loop at
 	movl	%ebx,%eax
Index: i386/vector.S
===================================================================
RCS file: /cvsroot/src/sys/arch/xen/i386/vector.S,v
retrieving revision 1.18
diff -u -r1.18 vector.S
--- i386/vector.S	25 Jun 2007 20:09:34 -0000	1.18
+++ i386/vector.S	27 Jun 2007 21:59:37 -0000
@@ -194,8 +194,8 @@
 	subl	$4,%esp							;\
 	pushl	$T_ASTFLT		/* trap # for doing ASTs */	;\
 	INTRENTRY							;\
+	movl	$_C_LABEL(Xdoreti), %esi; /* we now have a trap frame, so loop using doreti instead */ ;\
 IDTVEC(resume_/**/name/**/num)						\
-	/*movl	%esp,%ecx*/						;\
 	movl	$IREENT_MAGIC,TF_ERR(%esp)				;\
 	pushl	%ebx							;\
 	movl	CPUVAR(ISOURCES) + (num) * 4, %ebp			;\
@@ -216,7 +216,9 @@
 	CLI(%eax)							;\
 	unmask(num)			/* unmask it in hardware */	;\
 	late_ack(num)							;\
-	jmp	_C_LABEL(Xdoreti)	/* lower spl and do ASTs */	;\
+	IDEPTH_DECR							;\
+	popl	%ebx							;\
+	jmp	*%esi			/* lower spl and do ASTs */	;\
 
 # Just unmasking the event isn't enouth, we also need to
 # reassert the event pending bit if needed. For now just call
@@ -604,8 +606,24 @@
 6:	STIC(%eax)
     	jz	4f
 	call	_C_LABEL(stipending)
-	#testl	%eax,%eax		/* XXXcl */
-	#jnz	1b
+	testl	%eax,%eax
+	jz	4f
+	/* process pending interrupts */
+	CLI(%eax)
+	movl	CPUVAR(ILEVEL), %ebx
+	movl	$.Lalltraps_resume, %esi # address to resume loop at
+.Lalltraps_resume:
+	movl    %ebx,%eax		# get cpl
+	movl    CPUVAR(IUNMASK)(,%eax,4),%eax
+	andl    CPUVAR(IPENDING),%eax   # any non-masked bits left?
+	jz	7f
+	bsrl    %eax,%eax
+	btrl    %eax,CPUVAR(IPENDING)
+	movl    CPUVAR(ISOURCES)(,%eax,4),%eax
+	jmp     *IS_RESUME(%eax)
+7:	movl 	%ebx, CPUVAR(ILEVEL) #restore cpl
+	jmp 	.Lalltraps_checkast
+	
 4:
 #ifndef DIAGNOSTIC
 	INTRFASTEXIT
@@ -670,8 +688,23 @@
 6:	STIC(%eax)
     	jz	4f
 	call	_C_LABEL(stipending)
-	#testl	%eax,%eax		/* XXXcl */
-	#jnz	1b
+	testl	%eax,%eax
+	jz	4f
+	/* process for pending interrupts */
+	CLI(%eax)
+	movl	CPUVAR(ILEVEL), %ebx
+	movl	$.Ltrap0e_resume, %esi # address to resume loop at
+.Ltrap0e_resume:
+	movl    %ebx,%eax		# get cpl
+	movl    CPUVAR(IUNMASK)(,%eax,4),%eax
+	andl    CPUVAR(IPENDING),%eax   # any non-masked bits left?
+	jz	7f
+	bsrl    %eax,%eax
+	btrl    %eax,CPUVAR(IPENDING)
+	movl    CPUVAR(ISOURCES)(,%eax,4),%eax
+	jmp     *IS_RESUME(%eax)
+7:	movl	%ebx, CPUVAR(ILEVEL) #restore cpl
+	jmp	.Ltrap0e_checkast
 4:
 #ifndef DIAGNOSTIC
 	INTRFASTEXIT

--+HP7ph2BbKc20aGI--