forked from Minki/linux
[PATCH] x86-64: check vector in setup_ioapic_dest to verify if need setup_IO_APIC_irq
setup_IO_APIC_irqs could fail to get vector for some device when you have too many devices, because at that time only boot cpu is online. So check vector for irq in setup_ioapic_dest and call setup_IO_APIC_irq to make sure IO-APIC irq-routing table is initialized. Also seperate setup_IO_APIC_irq from setup_IO_APIC_irqs. Signed-off-by: Yinghai Lu <yinghai.lu@amd.com> Signed-off-by: Andi Kleen <ak@suse.de> Cc: Andi Kleen <ak@suse.de> Cc: "Eric W. Biederman" <ebiederm@xmission.com> Cc: Ingo Molnar <mingo@elte.hu> Signed-off-by: Andrew Morton <akpm@osdl.org>
This commit is contained in:
parent
f6ca8083c2
commit
ad892f5e0d
@ -789,28 +789,66 @@ static void ioapic_register_intr(int irq, int vector, unsigned long trigger)
|
||||
handle_edge_irq, "edge");
|
||||
}
|
||||
}
|
||||
static void __init setup_IO_APIC_irq(int apic, int pin, int idx, int irq)
|
||||
{
|
||||
struct IO_APIC_route_entry entry;
|
||||
int vector;
|
||||
unsigned long flags;
|
||||
|
||||
|
||||
/*
|
||||
* add it to the IO-APIC irq-routing table:
|
||||
*/
|
||||
memset(&entry,0,sizeof(entry));
|
||||
|
||||
entry.delivery_mode = INT_DELIVERY_MODE;
|
||||
entry.dest_mode = INT_DEST_MODE;
|
||||
entry.mask = 0; /* enable IRQ */
|
||||
entry.dest.logical.logical_dest = cpu_mask_to_apicid(TARGET_CPUS);
|
||||
|
||||
entry.trigger = irq_trigger(idx);
|
||||
entry.polarity = irq_polarity(idx);
|
||||
|
||||
if (irq_trigger(idx)) {
|
||||
entry.trigger = 1;
|
||||
entry.mask = 1;
|
||||
entry.dest.logical.logical_dest = cpu_mask_to_apicid(TARGET_CPUS);
|
||||
}
|
||||
|
||||
if (!apic && !IO_APIC_IRQ(irq))
|
||||
return;
|
||||
|
||||
if (IO_APIC_IRQ(irq)) {
|
||||
cpumask_t mask;
|
||||
vector = assign_irq_vector(irq, TARGET_CPUS, &mask);
|
||||
if (vector < 0)
|
||||
return;
|
||||
|
||||
entry.dest.logical.logical_dest = cpu_mask_to_apicid(mask);
|
||||
entry.vector = vector;
|
||||
|
||||
ioapic_register_intr(irq, vector, IOAPIC_AUTO);
|
||||
if (!apic && (irq < 16))
|
||||
disable_8259A_irq(irq);
|
||||
}
|
||||
|
||||
ioapic_write_entry(apic, pin, entry);
|
||||
|
||||
spin_lock_irqsave(&ioapic_lock, flags);
|
||||
set_native_irq_info(irq, TARGET_CPUS);
|
||||
spin_unlock_irqrestore(&ioapic_lock, flags);
|
||||
|
||||
}
|
||||
|
||||
static void __init setup_IO_APIC_irqs(void)
|
||||
{
|
||||
struct IO_APIC_route_entry entry;
|
||||
int apic, pin, idx, irq, first_notcon = 1, vector;
|
||||
unsigned long flags;
|
||||
int apic, pin, idx, irq, first_notcon = 1;
|
||||
|
||||
apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n");
|
||||
|
||||
for (apic = 0; apic < nr_ioapics; apic++) {
|
||||
for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) {
|
||||
|
||||
/*
|
||||
* add it to the IO-APIC irq-routing table:
|
||||
*/
|
||||
memset(&entry,0,sizeof(entry));
|
||||
|
||||
entry.delivery_mode = INT_DELIVERY_MODE;
|
||||
entry.dest_mode = INT_DEST_MODE;
|
||||
entry.mask = 0; /* enable IRQ */
|
||||
entry.dest.logical.logical_dest = cpu_mask_to_apicid(TARGET_CPUS);
|
||||
|
||||
idx = find_irq_entry(apic,pin,mp_INT);
|
||||
if (idx == -1) {
|
||||
if (first_notcon) {
|
||||
@ -821,39 +859,11 @@ static void __init setup_IO_APIC_irqs(void)
|
||||
continue;
|
||||
}
|
||||
|
||||
entry.trigger = irq_trigger(idx);
|
||||
entry.polarity = irq_polarity(idx);
|
||||
|
||||
if (irq_trigger(idx)) {
|
||||
entry.trigger = 1;
|
||||
entry.mask = 1;
|
||||
entry.dest.logical.logical_dest = cpu_mask_to_apicid(TARGET_CPUS);
|
||||
}
|
||||
|
||||
irq = pin_2_irq(idx, apic, pin);
|
||||
add_pin_to_irq(irq, apic, pin);
|
||||
|
||||
if (!apic && !IO_APIC_IRQ(irq))
|
||||
continue;
|
||||
setup_IO_APIC_irq(apic, pin, idx, irq);
|
||||
|
||||
if (IO_APIC_IRQ(irq)) {
|
||||
cpumask_t mask;
|
||||
vector = assign_irq_vector(irq, TARGET_CPUS, &mask);
|
||||
if (vector < 0)
|
||||
continue;
|
||||
|
||||
entry.dest.logical.logical_dest = cpu_mask_to_apicid(mask);
|
||||
entry.vector = vector;
|
||||
|
||||
ioapic_register_intr(irq, vector, IOAPIC_AUTO);
|
||||
if (!apic && (irq < 16))
|
||||
disable_8259A_irq(irq);
|
||||
}
|
||||
ioapic_write_entry(apic, pin, entry);
|
||||
|
||||
spin_lock_irqsave(&ioapic_lock, flags);
|
||||
set_native_irq_info(irq, TARGET_CPUS);
|
||||
spin_unlock_irqrestore(&ioapic_lock, flags);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2139,7 +2149,15 @@ void __init setup_ioapic_dest(void)
|
||||
if (irq_entry == -1)
|
||||
continue;
|
||||
irq = pin_2_irq(irq_entry, ioapic, pin);
|
||||
set_ioapic_affinity_irq(irq, TARGET_CPUS);
|
||||
|
||||
/* setup_IO_APIC_irqs could fail to get vector for some device
|
||||
* when you have too many devices, because at that time only boot
|
||||
* cpu is online.
|
||||
*/
|
||||
if(!irq_vector[irq])
|
||||
setup_IO_APIC_irq(ioapic, pin, irq_entry, irq);
|
||||
else
|
||||
set_ioapic_affinity_irq(irq, TARGET_CPUS);
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user