Skip to content

Commit

Permalink
x86: change FIRST_SYSTEM_VECTOR to a variable
Browse files Browse the repository at this point in the history
The SGI UV system needs several more system vectors than a vanilla
x86_64 system.  Rather than burden the other archs with extra system
vectors that they don't use, change FIRST_SYSTEM_VECTOR to a variable,
so that it can be dynamic.

Signed-off-by: Alan Mayer <ajm@sgi.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
  • Loading branch information
Alan Mayer authored and Ingo Molnar committed May 12, 2008
1 parent 1a33195 commit 305b92a
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 27 deletions.
14 changes: 7 additions & 7 deletions arch/x86/kernel/apic_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -1351,13 +1351,13 @@ void __init smp_intr_init(void)
* The reschedule interrupt is a CPU-to-CPU reschedule-helper
* IPI, driven by wakeup.
*/
set_intr_gate(RESCHEDULE_VECTOR, reschedule_interrupt);
alloc_intr_gate(RESCHEDULE_VECTOR, reschedule_interrupt);

/* IPI for invalidation */
set_intr_gate(INVALIDATE_TLB_VECTOR, invalidate_interrupt);
alloc_intr_gate(INVALIDATE_TLB_VECTOR, invalidate_interrupt);

/* IPI for generic function call */
set_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt);
alloc_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt);
}
#endif

Expand All @@ -1370,15 +1370,15 @@ void __init apic_intr_init(void)
smp_intr_init();
#endif
/* self generated IPI for local APIC timer */
set_intr_gate(LOCAL_TIMER_VECTOR, apic_timer_interrupt);
alloc_intr_gate(LOCAL_TIMER_VECTOR, apic_timer_interrupt);

/* IPI vectors for APIC spurious and error interrupts */
set_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt);
set_intr_gate(ERROR_APIC_VECTOR, error_interrupt);
alloc_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt);
alloc_intr_gate(ERROR_APIC_VECTOR, error_interrupt);

/* thermal monitor LVT interrupt */
#ifdef CONFIG_X86_MCE_P4THERMAL
set_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt);
alloc_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt);
#endif
}

Expand Down
30 changes: 15 additions & 15 deletions arch/x86/kernel/i8259_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -493,33 +493,33 @@ void __init native_init_IRQ(void)
* The reschedule interrupt is a CPU-to-CPU reschedule-helper
* IPI, driven by wakeup.
*/
set_intr_gate(RESCHEDULE_VECTOR, reschedule_interrupt);
alloc_intr_gate(RESCHEDULE_VECTOR, reschedule_interrupt);

/* IPIs for invalidation */
set_intr_gate(INVALIDATE_TLB_VECTOR_START+0, invalidate_interrupt0);
set_intr_gate(INVALIDATE_TLB_VECTOR_START+1, invalidate_interrupt1);
set_intr_gate(INVALIDATE_TLB_VECTOR_START+2, invalidate_interrupt2);
set_intr_gate(INVALIDATE_TLB_VECTOR_START+3, invalidate_interrupt3);
set_intr_gate(INVALIDATE_TLB_VECTOR_START+4, invalidate_interrupt4);
set_intr_gate(INVALIDATE_TLB_VECTOR_START+5, invalidate_interrupt5);
set_intr_gate(INVALIDATE_TLB_VECTOR_START+6, invalidate_interrupt6);
set_intr_gate(INVALIDATE_TLB_VECTOR_START+7, invalidate_interrupt7);
alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+0, invalidate_interrupt0);
alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+1, invalidate_interrupt1);
alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+2, invalidate_interrupt2);
alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+3, invalidate_interrupt3);
alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+4, invalidate_interrupt4);
alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+5, invalidate_interrupt5);
alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+6, invalidate_interrupt6);
alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+7, invalidate_interrupt7);

/* IPI for generic function call */
set_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt);
alloc_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt);

/* Low priority IPI to cleanup after moving an irq */
set_intr_gate(IRQ_MOVE_CLEANUP_VECTOR, irq_move_cleanup_interrupt);
#endif
set_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt);
set_intr_gate(THRESHOLD_APIC_VECTOR, threshold_interrupt);
alloc_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt);
alloc_intr_gate(THRESHOLD_APIC_VECTOR, threshold_interrupt);

/* self generated IPI for local APIC timer */
set_intr_gate(LOCAL_TIMER_VECTOR, apic_timer_interrupt);
alloc_intr_gate(LOCAL_TIMER_VECTOR, apic_timer_interrupt);

/* IPI vectors for APIC spurious and error interrupts */
set_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt);
set_intr_gate(ERROR_APIC_VECTOR, error_interrupt);
alloc_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt);
alloc_intr_gate(ERROR_APIC_VECTOR, error_interrupt);

if (!acpi_ioapic)
setup_irq(2, &irq2);
Expand Down
8 changes: 6 additions & 2 deletions arch/x86/kernel/io_apic_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ int mp_irq_entries;

static int disable_timer_pin_1 __initdata;

int first_system_vector = 0xfe;

char system_vectors[NR_VECTORS] = { [0 ... NR_VECTORS-1] = SYS_VECTOR_FREE};

/*
* Rough estimation of how many shared IRQs there are, can
* be changed anytime.
Expand Down Expand Up @@ -1176,7 +1180,7 @@ static int __assign_irq_vector(int irq)
offset = current_offset;
next:
vector += 8;
if (vector >= FIRST_SYSTEM_VECTOR) {
if (vector >= first_system_vector) {
offset = (offset + 1) % 8;
vector = FIRST_DEVICE_VECTOR + offset;
}
Expand Down Expand Up @@ -2269,7 +2273,7 @@ void __init setup_IO_APIC(void)
int i;

/* Reserve all the system vectors. */
for (i = FIRST_SYSTEM_VECTOR; i < NR_VECTORS; i++)
for (i = first_system_vector; i < NR_VECTORS; i++)
set_bit(i, used_vectors);

enable_IO_APIC();
Expand Down
6 changes: 5 additions & 1 deletion arch/x86/kernel/io_apic_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ struct irq_cfg irq_cfg[NR_IRQS] __read_mostly = {

static int assign_irq_vector(int irq, cpumask_t mask);

int first_system_vector = 0xfe;

char system_vectors[NR_VECTORS] = { [0 ... NR_VECTORS-1] = SYS_VECTOR_FREE};

#define __apicdebuginit __init

int sis_apic_bug; /* not actually supported, dummy for compile */
Expand Down Expand Up @@ -730,7 +734,7 @@ static int __assign_irq_vector(int irq, cpumask_t mask)
offset = current_offset;
next:
vector += 8;
if (vector >= FIRST_SYSTEM_VECTOR) {
if (vector >= first_system_vector) {
/* If we run out of vectors on large boxen, must share them. */
offset = (offset + 1) % 8;
vector = FIRST_DEVICE_VECTOR + offset;
Expand Down
22 changes: 22 additions & 0 deletions include/asm-x86/desc.h
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,28 @@ static inline void set_intr_gate(unsigned int n, void *addr)
_set_gate(n, GATE_INTERRUPT, addr, 0, 0, __KERNEL_CS);
}

#define SYS_VECTOR_FREE 0
#define SYS_VECTOR_ALLOCED 1

extern int first_system_vector;
extern char system_vectors[];

static inline void alloc_system_vector(int vector)
{
if (system_vectors[vector] == SYS_VECTOR_FREE) {
system_vectors[vector] = SYS_VECTOR_ALLOCED;
if (first_system_vector > vector)
first_system_vector = vector;
} else
BUG();
}

static inline void alloc_intr_gate(unsigned int n, void *addr)
{
alloc_system_vector(n);
set_intr_gate(n, addr);
}

/*
* This routine sets up an interrupt gate at directory privilege level 3.
*/
Expand Down
2 changes: 0 additions & 2 deletions include/asm-x86/irq_vectors.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,6 @@
# define FIRST_DEVICE_VECTOR (IRQ15_VECTOR + 2)
#endif

#define FIRST_SYSTEM_VECTOR 0xef

#define NR_VECTORS 256

#define FPU_IRQ 13
Expand Down

0 comments on commit 305b92a

Please sign in to comment.