aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSuresh Siddha <suresh.b.siddha@intel.com>2010-01-13 19:19:11 -0500
committerH. Peter Anvin <hpa@zytor.com>2010-01-18 13:59:59 -0500
commit6579b474572fd54c583ac074e8e7aaae926c62ef (patch)
treed84740df8c254be8d8875c8caaedf2da3124076a
parent722b3654852e48b93367a63f8ada9ee1cd43f2d3 (diff)
x86, irq: Use 0x20 for the IRQ_MOVE_CLEANUP_VECTOR instead of 0x1f
After talking to some more folks inside intel (Peter Anvin, Asit Mallick), the safest option (for future compatibility etc) seen was to use vector 0x20 for IRQ_MOVE_CLEANUP_VECTOR instead of using vector 0x1f (which is documented as reserved vector in the Intel IA32 manuals). Also we don't need to reserve the entire privilege level (all 16 vectors in the priority bucket that IRQ_MOVE_CLEANUP_VECTOR falls into), as the x86 architecture (section 10.9.3 in SDM Vol3a) specifies that with in the priority level, the higher the vector number the higher the priority. And hence we don't need to reserve the complete priority level 0x20-0x2f for the IRQ migration cleanup logic. So change the IRQ_MOVE_CLEANUP_VECTOR to 0x20 and allow 0x21-0x2f to be used for device interrupts. 0x30-0x3f will be used for ISA interrupts (these also can be migrated in the context of IOAPIC and hence need to be at a higher priority level than IRQ_MOVE_CLEANUP_VECTOR). Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com> LKML-Reference: <20100114002118.521826763@sbs-t61.sc.intel.com> Cc: Yinghai Lu <yinghai@kernel.org> Cc: Eric W. Biederman <ebiederm@xmission.com> Cc: Maciej W. Rozycki <macro@linux-mips.org> Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r--arch/x86/include/asm/irq_vectors.h47
-rw-r--r--arch/x86/kernel/apic/io_apic.c4
2 files changed, 18 insertions, 33 deletions
diff --git a/arch/x86/include/asm/irq_vectors.h b/arch/x86/include/asm/irq_vectors.h
index 585a42810cf8..8767d99c4f64 100644
--- a/arch/x86/include/asm/irq_vectors.h
+++ b/arch/x86/include/asm/irq_vectors.h
@@ -28,19 +28,22 @@
28#define MCE_VECTOR 0x12 28#define MCE_VECTOR 0x12
29 29
30/* 30/*
31 * IDT vectors usable for external interrupt sources start 31 * IDT vectors usable for external interrupt sources start at 0x20.
32 * at 0x20: 32 * (0x80 is the syscall vector, 0x30-0x3f are for ISA)
33 * hpa said we can start from 0x1f.
34 * 0x1f is documented as reserved. However, the ability for the APIC
35 * to generate vectors starting at 0x10 is documented, as is the
36 * ability for the CPU to receive any vector number as an interrupt.
37 * 0x1f is used for IRQ_MOVE_CLEANUP_VECTOR since that vector needs
38 * an entire privilege level (16 vectors) all by itself at a higher
39 * priority than any actual device vector. Thus, by placing it in the
40 * otherwise-unusable 0x10 privilege level, we avoid wasting a full
41 * 16-vector block.
42 */ 33 */
43#define FIRST_EXTERNAL_VECTOR 0x1f 34#define FIRST_EXTERNAL_VECTOR 0x20
35/*
36 * We start allocating at 0x21 to spread out vectors evenly between
37 * priority levels. (0x80 is the syscall vector)
38 */
39#define VECTOR_OFFSET_START 1
40
41/*
42 * Reserve the lowest usable vector (and hence lowest priority) 0x20 for
43 * triggering cleanup after irq migration. 0x21-0x2f will still be used
44 * for device interrupts.
45 */
46#define IRQ_MOVE_CLEANUP_VECTOR FIRST_EXTERNAL_VECTOR
44 47
45#define IA32_SYSCALL_VECTOR 0x80 48#define IA32_SYSCALL_VECTOR 0x80
46#ifdef CONFIG_X86_32 49#ifdef CONFIG_X86_32
@@ -48,17 +51,7 @@
48#endif 51#endif
49 52
50/* 53/*
51 * Reserve the lowest usable priority level 0x10 - 0x1f for triggering 54 * Vectors 0x30-0x3f are used for ISA interrupts.
52 * cleanup after irq migration.
53 * this overlaps with the reserved range for cpu exceptions so this
54 * will need to be changed to 0x20 - 0x2f if the last cpu exception is
55 * ever allocated.
56 */
57
58#define IRQ_MOVE_CLEANUP_VECTOR FIRST_EXTERNAL_VECTOR
59
60/*
61 * Vectors 0x20-0x2f are used for ISA interrupts.
62 * round up to the next 16-vector boundary 55 * round up to the next 16-vector boundary
63 */ 56 */
64#define IRQ0_VECTOR ((FIRST_EXTERNAL_VECTOR + 16) & ~15) 57#define IRQ0_VECTOR ((FIRST_EXTERNAL_VECTOR + 16) & ~15)
@@ -132,14 +125,6 @@
132 */ 125 */
133#define MCE_SELF_VECTOR 0xeb 126#define MCE_SELF_VECTOR 0xeb
134 127
135/*
136 * First APIC vector available to drivers: (vectors 0x30-0xee). We
137 * start allocating at 0x31 to spread out vectors evenly between
138 * priority levels. (0x80 is the syscall vector)
139 */
140#define FIRST_DEVICE_VECTOR (IRQ15_VECTOR + 1)
141#define VECTOR_OFFSET_START 1
142
143#define NR_VECTORS 256 128#define NR_VECTORS 256
144 129
145#define FPU_IRQ 13 130#define FPU_IRQ 13
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index e9ba0903e9d5..409f4943dc1a 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -1162,7 +1162,7 @@ __assign_irq_vector(int irq, struct irq_cfg *cfg, const struct cpumask *mask)
1162 * Also, we've got to be careful not to trash gate 1162 * Also, we've got to be careful not to trash gate
1163 * 0x80, because int 0x80 is hm, kind of importantish. ;) 1163 * 0x80, because int 0x80 is hm, kind of importantish. ;)
1164 */ 1164 */
1165 static int current_vector = FIRST_DEVICE_VECTOR + VECTOR_OFFSET_START; 1165 static int current_vector = FIRST_EXTERNAL_VECTOR + VECTOR_OFFSET_START;
1166 static int current_offset = VECTOR_OFFSET_START % 8; 1166 static int current_offset = VECTOR_OFFSET_START % 8;
1167 unsigned int old_vector; 1167 unsigned int old_vector;
1168 int cpu, err; 1168 int cpu, err;
@@ -1199,7 +1199,7 @@ next:
1199 if (vector >= first_system_vector) { 1199 if (vector >= first_system_vector) {
1200 /* If out of vectors on large boxen, must share them. */ 1200 /* If out of vectors on large boxen, must share them. */
1201 offset = (offset + 1) % 8; 1201 offset = (offset + 1) % 8;
1202 vector = FIRST_DEVICE_VECTOR + offset; 1202 vector = FIRST_EXTERNAL_VECTOR + offset;
1203 } 1203 }
1204 if (unlikely(current_vector == vector)) 1204 if (unlikely(current_vector == vector))
1205 continue; 1205 continue;