Port-xen archive

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

Re: kernel: supervisor trap asynchronous system trap, code=0



On Thu, Jun 28, 2007 at 12:18:44AM +0200, Manuel Bouyer wrote:
> 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 found it: in alltraps, if there was pending interrrupt the code would jump
back to processing ASTs without checking if it's a user or kernel context.
The attached diff works fine for me, and includes the fix for the
read_psl() == 0 assertion failure proposed by Kazushi Marukawa (fixed to
handle deffered interrupts).
I'll commit it in a few hours, but it would still be good if someone could
double-check it :)
-- 
Manuel Bouyer, LIP6, Universite Paris VI. 
Manuel.Bouyer%lip6.fr@localhost
 NetBSD: 26 ans d'experience feront toujours la difference
--
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 28 Jun 2007 13:27:49 -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
@@ -690,6 +691,14 @@
 jne check_ras
 
 switch_return:
+ STIC(%ebx)
+ jz 1f
+ call _C_LABEL(stipending)
+ testl %eax,%eax
+ jz 1f
+ pushl CPUVAR(ILEVEL)
+ call _C_LABEL(Xspllower) # process pending interrupts
+1:
 movl %esi,%eax # return 'oldlwp'
 popl %edi
 popl %esi
@@ -780,9 +789,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 +830,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 28 Jun 2007 13:27:49 -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 28 Jun 2007 13:27:49 -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
@@ -578,6 +580,7 @@
 pushl %esp
 call _C_LABEL(trap)
 addl 4,ドル%esp
+.Lalltraps_checkusr:
 testb $CHK_UPL,TF_CS(%esp)
 jnz .Lalltraps_checkast
 #ifdef VM86
@@ -604,8 +607,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_checkusr
+ 
 4:
 #ifndef DIAGNOSTIC
 INTRFASTEXIT
@@ -644,6 +663,7 @@
 call _C_LABEL(trap)
 addl 4,ドル%esp
 addl 4,ドル%esp
+.Ltrap0e_checkusr:
 testb $CHK_UPL,TF_CS(%esp)
 jnz trap0e_checkast
 #ifdef VM86
@@ -670,8 +690,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_checkusr
 4:
 #ifndef DIAGNOSTIC
 INTRFASTEXIT


Home | Main Index | Thread Index | Old Index

AltStyle によって変換されたページ (->オリジナル) /