2008-10-23 05:26:29 +00:00
|
|
|
#ifndef _ASM_X86_IRQ_VECTORS_H
|
|
|
|
#define _ASM_X86_IRQ_VECTORS_H
|
2008-05-02 18:10:09 +00:00
|
|
|
|
2011-01-17 02:52:02 +00:00
|
|
|
#include <linux/threads.h>
|
2009-01-31 01:48:17 +00:00
|
|
|
/*
|
|
|
|
* Linux IRQ vector layout.
|
|
|
|
*
|
|
|
|
* There are 256 IDT entries (per CPU - each entry is 8 bytes) which can
|
|
|
|
* be defined by Linux. They are used as a jump table by the CPU when a
|
|
|
|
* given vector is triggered - by a CPU-external, CPU-internal or
|
|
|
|
* software-triggered event.
|
|
|
|
*
|
|
|
|
* Linux sets the kernel code address each entry jumps to early during
|
|
|
|
* bootup, and never changes them. This is the general layout of the
|
|
|
|
* IDT entries:
|
|
|
|
*
|
|
|
|
* Vectors 0 ... 31 : system traps and exceptions - hardcoded events
|
|
|
|
* Vectors 32 ... 127 : device interrupts
|
|
|
|
* Vector 128 : legacy int80 syscall interface
|
2011-01-17 02:52:07 +00:00
|
|
|
* Vectors 129 ... INVALIDATE_TLB_VECTOR_START-1 : device interrupts
|
|
|
|
* Vectors INVALIDATE_TLB_VECTOR_START ... 255 : special interrupts
|
2009-01-31 01:48:17 +00:00
|
|
|
*
|
|
|
|
* 64-bit x86 has per CPU IDT tables, 32-bit has one shared IDT table.
|
|
|
|
*
|
|
|
|
* This file enumerates the exact layout of them:
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define NMI_VECTOR 0x02
|
2009-05-27 19:56:58 +00:00
|
|
|
#define MCE_VECTOR 0x12
|
2008-05-02 18:10:09 +00:00
|
|
|
|
|
|
|
/*
|
2010-01-14 00:19:11 +00:00
|
|
|
* IDT vectors usable for external interrupt sources start at 0x20.
|
|
|
|
* (0x80 is the syscall vector, 0x30-0x3f are for ISA)
|
2008-05-02 18:10:09 +00:00
|
|
|
*/
|
2010-01-14 00:19:11 +00:00
|
|
|
#define FIRST_EXTERNAL_VECTOR 0x20
|
|
|
|
/*
|
|
|
|
* We start allocating at 0x21 to spread out vectors evenly between
|
|
|
|
* priority levels. (0x80 is the syscall vector)
|
|
|
|
*/
|
|
|
|
#define VECTOR_OFFSET_START 1
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Reserve the lowest usable vector (and hence lowest priority) 0x20 for
|
|
|
|
* triggering cleanup after irq migration. 0x21-0x2f will still be used
|
|
|
|
* for device interrupts.
|
|
|
|
*/
|
|
|
|
#define IRQ_MOVE_CLEANUP_VECTOR FIRST_EXTERNAL_VECTOR
|
2008-05-02 18:10:09 +00:00
|
|
|
|
2010-01-05 00:16:06 +00:00
|
|
|
#define IA32_SYSCALL_VECTOR 0x80
|
2008-05-02 18:10:09 +00:00
|
|
|
#ifdef CONFIG_X86_32
|
2009-01-31 01:48:17 +00:00
|
|
|
# define SYSCALL_VECTOR 0x80
|
2008-05-02 18:10:09 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
/*
|
2010-01-14 00:19:11 +00:00
|
|
|
* Vectors 0x30-0x3f are used for ISA interrupts.
|
2010-01-05 00:16:06 +00:00
|
|
|
* round up to the next 16-vector boundary
|
2008-05-02 18:10:09 +00:00
|
|
|
*/
|
2010-01-05 00:16:06 +00:00
|
|
|
#define IRQ0_VECTOR ((FIRST_EXTERNAL_VECTOR + 16) & ~15)
|
2009-01-31 01:48:17 +00:00
|
|
|
|
|
|
|
#define IRQ1_VECTOR (IRQ0_VECTOR + 1)
|
|
|
|
#define IRQ2_VECTOR (IRQ0_VECTOR + 2)
|
|
|
|
#define IRQ3_VECTOR (IRQ0_VECTOR + 3)
|
|
|
|
#define IRQ4_VECTOR (IRQ0_VECTOR + 4)
|
|
|
|
#define IRQ5_VECTOR (IRQ0_VECTOR + 5)
|
|
|
|
#define IRQ6_VECTOR (IRQ0_VECTOR + 6)
|
|
|
|
#define IRQ7_VECTOR (IRQ0_VECTOR + 7)
|
|
|
|
#define IRQ8_VECTOR (IRQ0_VECTOR + 8)
|
|
|
|
#define IRQ9_VECTOR (IRQ0_VECTOR + 9)
|
|
|
|
#define IRQ10_VECTOR (IRQ0_VECTOR + 10)
|
|
|
|
#define IRQ11_VECTOR (IRQ0_VECTOR + 11)
|
|
|
|
#define IRQ12_VECTOR (IRQ0_VECTOR + 12)
|
|
|
|
#define IRQ13_VECTOR (IRQ0_VECTOR + 13)
|
|
|
|
#define IRQ14_VECTOR (IRQ0_VECTOR + 14)
|
|
|
|
#define IRQ15_VECTOR (IRQ0_VECTOR + 15)
|
2008-05-02 18:10:09 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Special IRQ vectors used by the SMP architecture, 0xf0-0xff
|
|
|
|
*
|
|
|
|
* some of the following vectors are 'rare', they are merged
|
|
|
|
* into a single vector (CALL_FUNCTION_VECTOR) to save vector space.
|
|
|
|
* TLB, reschedule and local APIC vectors are performance-critical.
|
|
|
|
*/
|
2009-01-21 08:26:06 +00:00
|
|
|
|
2009-01-31 01:10:03 +00:00
|
|
|
#define SPURIOUS_APIC_VECTOR 0xff
|
2009-01-31 01:06:50 +00:00
|
|
|
/*
|
|
|
|
* Sanity check
|
|
|
|
*/
|
|
|
|
#if ((SPURIOUS_APIC_VECTOR & 0x0F) != 0x0F)
|
|
|
|
# error SPURIOUS_APIC_VECTOR definition error
|
|
|
|
#endif
|
|
|
|
|
2009-01-31 01:10:03 +00:00
|
|
|
#define ERROR_APIC_VECTOR 0xfe
|
|
|
|
#define RESCHEDULE_VECTOR 0xfd
|
|
|
|
#define CALL_FUNCTION_VECTOR 0xfc
|
|
|
|
#define CALL_FUNCTION_SINGLE_VECTOR 0xfb
|
|
|
|
#define THERMAL_APIC_VECTOR 0xfa
|
2009-04-28 21:32:56 +00:00
|
|
|
#define THRESHOLD_APIC_VECTOR 0xf9
|
x86: fix panic with interrupts off (needed for MCE)
For some time each panic() called with interrupts disabled
triggered the !irqs_disabled() WARN_ON in smp_call_function(),
producing ugly backtraces and confusing users.
This is a common situation with machine checks for example which
tend to call panic with interrupts disabled, but will also hit
in other situations e.g. panic during early boot. In fact it
means that panic cannot be called in many circumstances, which
would be bad.
This all started with the new fancy queued smp_call_function,
which is then used by the shutdown path to shut down the other
CPUs.
On closer examination it turned out that the fancy RCU
smp_call_function() does lots of things not suitable in a panic
situation anyways, like allocating memory and relying on complex
system state.
I originally tried to patch this over by checking for panic
there, but it was quite complicated and the original patch
was also not very popular. This also didn't fix some of the
underlying complexity problems.
The new code in post 2.6.29 tries to patch around this by
checking for oops_in_progress, but that is not enough to make
this fully safe and I don't think that's a real solution
because panic has to be reliable.
So instead use an own vector to reboot. This makes the reboot
code extremly straight forward, which is definitely a big plus
in a panic situation where it is important to avoid relying on
too much kernel state. The new simple code is also safe to be
called from interupts off region because it is very very simple.
There can be situations where it is important that panic
is reliable. For example on a fatal machine check the panic
is needed to get the system up again and running as quickly
as possible. So it's important that panic is reliable and
all function it calls simple.
This is why I came up with this simple vector scheme.
It's very hard to beat in simplicity. Vectors are not
particularly precious anymore since all big systems are
using per CPU vectors.
Another possibility would have been to use an NMI similar
to kdump, but there is still the problem that NMIs don't
work reliably on some systems due to BIOS issues. NMIs
would have been able to stop CPUs running with interrupts
off too. In the sake of universal reliability I opted for
using a non NMI vector for now.
I put the reboot vector into the highest priority bucket of
the APIC vectors and moved the 64bit UV_BAU message down
instead into the next lower priority.
[ Impact: bug fix, fixes an old regression ]
Signed-off-by: Andi Kleen <ak@linux.intel.com>
Signed-off-by: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
2009-05-27 19:56:52 +00:00
|
|
|
#define REBOOT_VECTOR 0xf8
|
2008-05-02 18:10:09 +00:00
|
|
|
|
2009-01-31 01:23:27 +00:00
|
|
|
/*
|
2009-03-04 18:56:05 +00:00
|
|
|
* Generic system vector for platform specific use
|
2009-01-31 01:23:27 +00:00
|
|
|
*/
|
2011-01-17 02:52:02 +00:00
|
|
|
#define X86_PLATFORM_IPI_VECTOR 0xf7
|
2009-01-31 01:23:27 +00:00
|
|
|
|
2009-03-04 18:56:05 +00:00
|
|
|
/*
|
2010-10-14 06:01:34 +00:00
|
|
|
* IRQ work vector:
|
2009-03-04 18:56:05 +00:00
|
|
|
*/
|
2011-01-17 02:52:02 +00:00
|
|
|
#define IRQ_WORK_VECTOR 0xf6
|
2009-03-04 18:56:05 +00:00
|
|
|
|
2011-01-17 02:52:02 +00:00
|
|
|
#define UV_BAU_MESSAGE 0xf5
|
x86: fix panic with interrupts off (needed for MCE)
For some time each panic() called with interrupts disabled
triggered the !irqs_disabled() WARN_ON in smp_call_function(),
producing ugly backtraces and confusing users.
This is a common situation with machine checks for example which
tend to call panic with interrupts disabled, but will also hit
in other situations e.g. panic during early boot. In fact it
means that panic cannot be called in many circumstances, which
would be bad.
This all started with the new fancy queued smp_call_function,
which is then used by the shutdown path to shut down the other
CPUs.
On closer examination it turned out that the fancy RCU
smp_call_function() does lots of things not suitable in a panic
situation anyways, like allocating memory and relying on complex
system state.
I originally tried to patch this over by checking for panic
there, but it was quite complicated and the original patch
was also not very popular. This also didn't fix some of the
underlying complexity problems.
The new code in post 2.6.29 tries to patch around this by
checking for oops_in_progress, but that is not enough to make
this fully safe and I don't think that's a real solution
because panic has to be reliable.
So instead use an own vector to reboot. This makes the reboot
code extremly straight forward, which is definitely a big plus
in a panic situation where it is important to avoid relying on
too much kernel state. The new simple code is also safe to be
called from interupts off region because it is very very simple.
There can be situations where it is important that panic
is reliable. For example on a fatal machine check the panic
is needed to get the system up again and running as quickly
as possible. So it's important that panic is reliable and
all function it calls simple.
This is why I came up with this simple vector scheme.
It's very hard to beat in simplicity. Vectors are not
particularly precious anymore since all big systems are
using per CPU vectors.
Another possibility would have been to use an NMI similar
to kdump, but there is still the problem that NMIs don't
work reliably on some systems due to BIOS issues. NMIs
would have been able to stop CPUs running with interrupts
off too. In the sake of universal reliability I opted for
using a non NMI vector for now.
I put the reboot vector into the highest priority bucket of
the APIC vectors and moved the 64bit UV_BAU message down
instead into the next lower priority.
[ Impact: bug fix, fixes an old regression ]
Signed-off-by: Andi Kleen <ak@linux.intel.com>
Signed-off-by: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
2009-05-27 19:56:52 +00:00
|
|
|
|
2009-05-27 19:56:54 +00:00
|
|
|
/*
|
|
|
|
* Self IPI vector for machine checks
|
|
|
|
*/
|
2011-01-17 02:52:02 +00:00
|
|
|
#define MCE_SELF_VECTOR 0xf4
|
2009-05-27 19:56:54 +00:00
|
|
|
|
2010-05-14 11:40:51 +00:00
|
|
|
/* Xen vector callback to receive events in a HVM domain */
|
2011-01-17 02:52:02 +00:00
|
|
|
#define XEN_HVM_EVTCHN_CALLBACK 0xf3
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Local APIC timer IRQ vector is on a different priority level,
|
|
|
|
* to work around the 'lost local interrupt if more than 2 IRQ
|
|
|
|
* sources per level' errata.
|
|
|
|
*/
|
|
|
|
#define LOCAL_TIMER_VECTOR 0xef
|
|
|
|
|
2011-01-17 02:52:07 +00:00
|
|
|
/* up to 32 vectors used for spreading out TLB flushes: */
|
|
|
|
#if NR_CPUS <= 32
|
2011-03-03 10:55:29 +00:00
|
|
|
# define NUM_INVALIDATE_TLB_VECTORS (NR_CPUS)
|
2011-01-17 02:52:07 +00:00
|
|
|
#else
|
2011-03-03 10:55:29 +00:00
|
|
|
# define NUM_INVALIDATE_TLB_VECTORS (32)
|
2011-01-17 02:52:07 +00:00
|
|
|
#endif
|
|
|
|
|
2011-03-03 10:55:29 +00:00
|
|
|
#define INVALIDATE_TLB_VECTOR_END (0xee)
|
2011-01-17 02:52:02 +00:00
|
|
|
#define INVALIDATE_TLB_VECTOR_START \
|
2011-03-03 10:55:29 +00:00
|
|
|
(INVALIDATE_TLB_VECTOR_END-NUM_INVALIDATE_TLB_VECTORS+1)
|
2010-05-14 11:40:51 +00:00
|
|
|
|
2009-01-31 01:48:17 +00:00
|
|
|
#define NR_VECTORS 256
|
2008-05-02 18:10:09 +00:00
|
|
|
|
2009-01-31 01:48:17 +00:00
|
|
|
#define FPU_IRQ 13
|
2008-05-02 18:10:09 +00:00
|
|
|
|
2009-01-31 01:48:17 +00:00
|
|
|
#define FIRST_VM86_IRQ 3
|
|
|
|
#define LAST_VM86_IRQ 15
|
2009-01-31 02:06:17 +00:00
|
|
|
|
|
|
|
#ifndef __ASSEMBLY__
|
|
|
|
static inline int invalid_vm86_irq(int irq)
|
|
|
|
{
|
2009-02-23 19:56:59 +00:00
|
|
|
return irq < FIRST_VM86_IRQ || irq > LAST_VM86_IRQ;
|
2009-01-31 02:06:17 +00:00
|
|
|
}
|
|
|
|
#endif
|
2008-05-02 18:10:09 +00:00
|
|
|
|
2009-01-31 01:56:44 +00:00
|
|
|
/*
|
|
|
|
* Size the maximum number of interrupts.
|
|
|
|
*
|
|
|
|
* If the irq_desc[] array has a sparse layout, we can size things
|
|
|
|
* generously - it scales up linearly with the maximum number of CPUs,
|
|
|
|
* and the maximum number of IO-APICs, whichever is higher.
|
|
|
|
*
|
|
|
|
* In other cases we size more conservatively, to not create too large
|
|
|
|
* static arrays.
|
|
|
|
*/
|
|
|
|
|
2009-01-31 01:48:17 +00:00
|
|
|
#define NR_IRQS_LEGACY 16
|
2008-12-06 02:58:32 +00:00
|
|
|
|
2009-01-31 01:56:44 +00:00
|
|
|
#define IO_APIC_VECTOR_LIMIT ( 32 * MAX_IO_APICS )
|
|
|
|
|
2009-01-31 01:21:42 +00:00
|
|
|
#ifdef CONFIG_X86_IO_APIC
|
2009-01-31 01:56:44 +00:00
|
|
|
# ifdef CONFIG_SPARSE_IRQ
|
x86: Increase NR_IRQS and nr_irqs
I have a system with lots of igb and ixgbe, when iov/vf are
enabled for them, we hit the limit of 3064.
when system has 20 pcie installed, and one card has 2
functions, and one function needs 64 msi-x,
may need 20 * 2 * 64 = 2560 for msi-x
but if iov and vf are enabled
may need 20 * 2 * 64 * 3 = 7680 for msi-x
assume system with 5 ioapic, nr_irqs_gsi will be 120.
NR_CPUS = 512, and nr_cpu_ids = 128
will have NR_IRQS = 256 + 512 * 64 = 33024
will have nr_irqs = 120 + 8 * 128 + 120 * 64 = 8824
When SPARSE_IRQ is not set, there is no increase with kernel data
size.
when NR_CPUS=128, and SPARSE_IRQ is set:
text data bss dec hex filename
21837444 4216564 12480736 38534744 24bfe58 vmlinux.before
21837442 4216580 12480736 38534758 24bfe66 vmlinux.after
when NR_CPUS=4096, and SPARSE_IRQ is set
text data bss dec hex filename
21878619 5610244 13415392 40904255 270263f vmlinux.before
21878617 5610244 13415392 40904253 270263d vmlinux.after
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
LKML-Reference: <4B398ECD.1080506@kernel.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2009-12-29 05:08:29 +00:00
|
|
|
# define CPU_VECTOR_LIMIT (64 * NR_CPUS)
|
2009-01-31 01:56:44 +00:00
|
|
|
# define NR_IRQS \
|
|
|
|
(CPU_VECTOR_LIMIT > IO_APIC_VECTOR_LIMIT ? \
|
|
|
|
(NR_VECTORS + CPU_VECTOR_LIMIT) : \
|
|
|
|
(NR_VECTORS + IO_APIC_VECTOR_LIMIT))
|
|
|
|
# else
|
x86: Increase NR_IRQS and nr_irqs
I have a system with lots of igb and ixgbe, when iov/vf are
enabled for them, we hit the limit of 3064.
when system has 20 pcie installed, and one card has 2
functions, and one function needs 64 msi-x,
may need 20 * 2 * 64 = 2560 for msi-x
but if iov and vf are enabled
may need 20 * 2 * 64 * 3 = 7680 for msi-x
assume system with 5 ioapic, nr_irqs_gsi will be 120.
NR_CPUS = 512, and nr_cpu_ids = 128
will have NR_IRQS = 256 + 512 * 64 = 33024
will have nr_irqs = 120 + 8 * 128 + 120 * 64 = 8824
When SPARSE_IRQ is not set, there is no increase with kernel data
size.
when NR_CPUS=128, and SPARSE_IRQ is set:
text data bss dec hex filename
21837444 4216564 12480736 38534744 24bfe58 vmlinux.before
21837442 4216580 12480736 38534758 24bfe66 vmlinux.after
when NR_CPUS=4096, and SPARSE_IRQ is set
text data bss dec hex filename
21878619 5610244 13415392 40904255 270263f vmlinux.before
21878617 5610244 13415392 40904253 270263d vmlinux.after
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
LKML-Reference: <4B398ECD.1080506@kernel.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2009-12-29 05:08:29 +00:00
|
|
|
# define CPU_VECTOR_LIMIT (32 * NR_CPUS)
|
|
|
|
# define NR_IRQS \
|
|
|
|
(CPU_VECTOR_LIMIT < IO_APIC_VECTOR_LIMIT ? \
|
|
|
|
(NR_VECTORS + CPU_VECTOR_LIMIT) : \
|
|
|
|
(NR_VECTORS + IO_APIC_VECTOR_LIMIT))
|
2009-01-31 01:50:46 +00:00
|
|
|
# endif
|
2009-01-31 01:21:42 +00:00
|
|
|
#else /* !CONFIG_X86_IO_APIC: */
|
2009-01-31 01:56:44 +00:00
|
|
|
# define NR_IRQS NR_IRQS_LEGACY
|
2008-11-04 22:10:13 +00:00
|
|
|
#endif
|
2008-05-02 18:10:09 +00:00
|
|
|
|
2008-10-23 05:26:29 +00:00
|
|
|
#endif /* _ASM_X86_IRQ_VECTORS_H */
|