Author: jhb
Date: Thu Jan 13 17:00:22 2011
New Revision: 217360
URL: http://svn.freebsd.org/changeset/base/217360

Log:
  If an interrupt on an I/O APIC is moved to a different CPU after it has
  started to execute, it seems that the corresponding ISR bit in the "old"
  local APIC can be cleared.  This causes the local APIC interrupt routine
  to fail to find an interrupt to service.  Rather than panic'ing in this
  case, simply return from the interrupt without sending an EOI to the
  local APIC.  If there are any other pending interrupts in other ISR
  registers, the local APIC will assert a new interrupt.
  
  Tested by:    steve

Modified:
  head/sys/amd64/amd64/apic_vector.S
  head/sys/i386/i386/apic_vector.s
  head/sys/x86/x86/local_apic.c

Modified: head/sys/amd64/amd64/apic_vector.S
==============================================================================
--- head/sys/amd64/amd64/apic_vector.S  Thu Jan 13 16:42:16 2011        
(r217359)
+++ head/sys/amd64/amd64/apic_vector.S  Thu Jan 13 17:00:22 2011        
(r217360)
@@ -58,17 +58,15 @@ IDTVEC(vec_name) ;                                          
        \
        FAKE_MCOUNT(TF_RIP(%rsp)) ;                                     \
        movq    lapic, %rdx ;   /* pointer to local APIC */             \
        movl    LA_ISR + 16 * (index)(%rdx), %eax ;     /* load ISR */  \
-       bsrl    %eax, %eax ;    /* index of highset set bit in ISR */   \
-       jz      2f ;                                                    \
+       bsrl    %eax, %eax ;    /* index of highest set bit in ISR */   \
+       jz      1f ;                                                    \
        addl    $(32 * index),%eax ;                                    \
-1: ;                                                                   \
        movq    %rsp, %rsi      ;                                       \
        movl    %eax, %edi ;    /* pass the IRQ */                      \
        call    lapic_handle_intr ;                                     \
+1: ;                                                                   \
        MEXITCOUNT ;                                                    \
-       jmp     doreti ;                                                \
-2:     movl    $-1, %eax ;     /* send a vector of -1 */               \
-       jmp     1b
+       jmp     doreti
 
 /*
  * Handle "spurious INTerrupts".

Modified: head/sys/i386/i386/apic_vector.s
==============================================================================
--- head/sys/i386/i386/apic_vector.s    Thu Jan 13 16:42:16 2011        
(r217359)
+++ head/sys/i386/i386/apic_vector.s    Thu Jan 13 17:00:22 2011        
(r217360)
@@ -60,18 +60,16 @@ IDTVEC(vec_name) ;                                          
        \
        FAKE_MCOUNT(TF_EIP(%esp)) ;                                     \
        movl    lapic, %edx ;   /* pointer to local APIC */             \
        movl    LA_ISR + 16 * (index)(%edx), %eax ;     /* load ISR */  \
-       bsrl    %eax, %eax ;    /* index of highset set bit in ISR */   \
-       jz      2f ;                                                    \
+       bsrl    %eax, %eax ;    /* index of highest set bit in ISR */   \
+       jz      1f ;                                                    \
        addl    $(32 * index),%eax ;                                    \
-1: ;                                                                   \
        pushl   %esp            ;                                       \
        pushl   %eax ;          /* pass the IRQ */                      \
        call    lapic_handle_intr ;                                     \
        addl    $8, %esp ;      /* discard parameter */                 \
+1: ;                                                                   \
        MEXITCOUNT ;                                                    \
-       jmp     doreti ;                                                \
-2:     movl    $-1, %eax ;     /* send a vector of -1 */               \
-       jmp     1b
+       jmp     doreti
 
 /*
  * Handle "spurious INTerrupts".

Modified: head/sys/x86/x86/local_apic.c
==============================================================================
--- head/sys/x86/x86/local_apic.c       Thu Jan 13 16:42:16 2011        
(r217359)
+++ head/sys/x86/x86/local_apic.c       Thu Jan 13 17:00:22 2011        
(r217360)
@@ -780,8 +780,6 @@ lapic_handle_intr(int vector, struct tra
 {
        struct intsrc *isrc;
 
-       if (vector == -1)
-               panic("Couldn't get vector from ISR!");
        isrc = intr_lookup_source(apic_idt_to_irq(PCPU_GET(apic_id),
            vector));
        intr_execute_handlers(isrc, frame);
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to