Commit 78b599ae authored by Andi Kleen's avatar Andi Kleen Committed by Linus Torvalds

x86_64: Don't rely on a unique IO-APIC ID

Linux 64bit only uses the IO-APIC ID as an internal cookie. In the future
there could be some cases where the IO-APIC IDs are not unique because
they share an 8 bit space with CPUs and if there are enough CPUs
it is difficult to get them that. But Linux needs the io apic ID
internally for its data structures. Assign unique IO APIC ids on
table parsing.

TBD do for 32bit too
Signed-off-by: default avatarAndi Kleen <ak@suse.de>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 9d531cc1
...@@ -649,6 +649,20 @@ static int mp_find_ioapic(int gsi) ...@@ -649,6 +649,20 @@ static int mp_find_ioapic(int gsi)
return -1; return -1;
} }
static u8 uniq_ioapic_id(u8 id)
{
int i;
DECLARE_BITMAP(used, 256);
bitmap_zero(used, 256);
for (i = 0; i < nr_ioapics; i++) {
struct mpc_config_ioapic *ia = &mp_ioapics[i];
__set_bit(ia->mpc_apicid, used);
}
if (!test_bit(id, used))
return id;
return find_first_zero_bit(used, 256);
}
void __init mp_register_ioapic(u8 id, u32 address, u32 gsi_base) void __init mp_register_ioapic(u8 id, u32 address, u32 gsi_base)
{ {
int idx = 0; int idx = 0;
...@@ -656,14 +670,14 @@ void __init mp_register_ioapic(u8 id, u32 address, u32 gsi_base) ...@@ -656,14 +670,14 @@ void __init mp_register_ioapic(u8 id, u32 address, u32 gsi_base)
if (bad_ioapic(address)) if (bad_ioapic(address))
return; return;
idx = nr_ioapics++; idx = nr_ioapics;
mp_ioapics[idx].mpc_type = MP_IOAPIC; mp_ioapics[idx].mpc_type = MP_IOAPIC;
mp_ioapics[idx].mpc_flags = MPC_APIC_USABLE; mp_ioapics[idx].mpc_flags = MPC_APIC_USABLE;
mp_ioapics[idx].mpc_apicaddr = address; mp_ioapics[idx].mpc_apicaddr = address;
set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address); set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address);
mp_ioapics[idx].mpc_apicid = id; mp_ioapics[idx].mpc_apicid = uniq_ioapic_id(id);
mp_ioapics[idx].mpc_apicver = 0; mp_ioapics[idx].mpc_apicver = 0;
/* /*
...@@ -680,6 +694,8 @@ void __init mp_register_ioapic(u8 id, u32 address, u32 gsi_base) ...@@ -680,6 +694,8 @@ void __init mp_register_ioapic(u8 id, u32 address, u32 gsi_base)
mp_ioapics[idx].mpc_apicaddr, mp_ioapics[idx].mpc_apicaddr,
mp_ioapic_routing[idx].gsi_start, mp_ioapic_routing[idx].gsi_start,
mp_ioapic_routing[idx].gsi_end); mp_ioapic_routing[idx].gsi_end);
nr_ioapics++;
} }
void __init void __init
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment