aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86_64/kernel/mpparse.c
diff options
context:
space:
mode:
authorAndi Kleen <ak@suse.de>2007-07-21 11:09:53 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-21 21:37:07 -0400
commit78b599aed61a1098444558e74c93745f22eda6cb (patch)
treef6132e3cf2a2e39524a5d5edc05161e9682a5811 /arch/x86_64/kernel/mpparse.c
parent9d531cc1193693f2d2e5ef2532a877481b118be6 (diff)
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: Andi Kleen <ak@suse.de> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/x86_64/kernel/mpparse.c')
-rw-r--r--arch/x86_64/kernel/mpparse.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/arch/x86_64/kernel/mpparse.c b/arch/x86_64/kernel/mpparse.c
index 61ae57eb9e4..0ec84909d84 100644
--- a/arch/x86_64/kernel/mpparse.c
+++ b/arch/x86_64/kernel/mpparse.c
@@ -649,6 +649,20 @@ static int mp_find_ioapic(int gsi)
649 return -1; 649 return -1;
650} 650}
651 651
652static u8 uniq_ioapic_id(u8 id)
653{
654 int i;
655 DECLARE_BITMAP(used, 256);
656 bitmap_zero(used, 256);
657 for (i = 0; i < nr_ioapics; i++) {
658 struct mpc_config_ioapic *ia = &mp_ioapics[i];
659 __set_bit(ia->mpc_apicid, used);
660 }
661 if (!test_bit(id, used))
662 return id;
663 return find_first_zero_bit(used, 256);
664}
665
652void __init mp_register_ioapic(u8 id, u32 address, u32 gsi_base) 666void __init mp_register_ioapic(u8 id, u32 address, u32 gsi_base)
653{ 667{
654 int idx = 0; 668 int idx = 0;
@@ -656,14 +670,14 @@ void __init mp_register_ioapic(u8 id, u32 address, u32 gsi_base)
656 if (bad_ioapic(address)) 670 if (bad_ioapic(address))
657 return; 671 return;
658 672
659 idx = nr_ioapics++; 673 idx = nr_ioapics;
660 674
661 mp_ioapics[idx].mpc_type = MP_IOAPIC; 675 mp_ioapics[idx].mpc_type = MP_IOAPIC;
662 mp_ioapics[idx].mpc_flags = MPC_APIC_USABLE; 676 mp_ioapics[idx].mpc_flags = MPC_APIC_USABLE;
663 mp_ioapics[idx].mpc_apicaddr = address; 677 mp_ioapics[idx].mpc_apicaddr = address;
664 678
665 set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address); 679 set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address);
666 mp_ioapics[idx].mpc_apicid = id; 680 mp_ioapics[idx].mpc_apicid = uniq_ioapic_id(id);
667 mp_ioapics[idx].mpc_apicver = 0; 681 mp_ioapics[idx].mpc_apicver = 0;
668 682
669 /* 683 /*
@@ -680,6 +694,8 @@ void __init mp_register_ioapic(u8 id, u32 address, u32 gsi_base)
680 mp_ioapics[idx].mpc_apicaddr, 694 mp_ioapics[idx].mpc_apicaddr,
681 mp_ioapic_routing[idx].gsi_start, 695 mp_ioapic_routing[idx].gsi_start,
682 mp_ioapic_routing[idx].gsi_end); 696 mp_ioapic_routing[idx].gsi_end);
697
698 nr_ioapics++;
683} 699}
684 700
685void __init 701void __init