Port-xen archive

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

kernel: supervisor trap asynchronous system trap, code=0



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@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       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


Home | Main Index | Thread Index | Old Index