Skip to content
  • John Baldwin's avatar
    Dynamically allocate IRQ ranges on x86. · fd036dea
    John Baldwin authored
    Previously, x86 used static ranges of IRQ values for different types
    of I/O interrupts.  Interrupt pins on I/O APICs and 8259A PICs used
    IRQ values from 0 to 254.  MSI interrupts used a compile-time-defined
    range starting at 256, and Xen event channels used a
    compile-time-defined range after MSI.  Some recent systems have more
    than 255 I/O APIC interrupt pins which resulted in those IRQ values
    overflowing into the MSI range triggering an assertion failure.
    
    Replace statically assigned ranges with dynamic ranges.  Do a single
    pass computing the sizes of the IRQ ranges (PICs, MSI, Xen) to
    determine the total number of IRQs required.  Allocate the interrupt
    source and interrupt count arrays dynamically once this pass has
    completed.  To minimize runtime complexity these arrays are only sized
    once during bootup.  The PIC range is determined by the PICs present
    in the system.  The MSI and Xen ranges continue to use a fixed size,
    though this does make it possible to turn the MSI range size into a
    tunable in the future.
    
    As a result, various places are updated to use dynamic limits instead
    of constants.  In addition, the vmstat(8) utility has been taught to
    understand that some kernels may treat 'intrcnt' and 'intrnames' as
    pointers rather than arrays when extracting interrupt stats from a
    crashdump.  This is determined by the presence (vs absence) of a
    global 'nintrcnt' symbol.
    
    This change reverts r189404 which worked around a buggy BIOS which
    enumerated an I/O APIC twice (using the same memory mapped address for
    both entries but using an IRQ base of 256 for one entry and a valid
    IRQ base for the second entry).  Making the "base" of MSI IRQ values
    dynamic avoids the panic that r189404 worked around, and there may now
    be valid I/O APICs with an IRQ base above 256 which this workaround
    would incorrectly skip.
    
    If in the future the issue reported in PR 130483 reoccurs, we will
    have to add a pass over the I/O APIC entries in the MADT to detect
    duplicates using the memory mapped address and use some strategy to
    choose the "correct" one.
    
    While here, reserve room in intrcnts for the Hyper-V counters.
    
    PR:		229429, 130483
    Reviewed by:	kib, royger, cem
    Tested by:	royger (Xen), kib (DMAR)
    Approved by:	re (gjb)
    MFC after:	2 weeks
    Differential Revision:	https://reviews.freebsd.org/D16861
    fd036dea