diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86_64/kernel/mpparse.c | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/arch/x86_64/kernel/mpparse.c b/arch/x86_64/kernel/mpparse.c index 61ae57eb9e4c..0ec84909d846 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 | ||
652 | static 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 | |||
652 | void __init mp_register_ioapic(u8 id, u32 address, u32 gsi_base) | 666 | void __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 | ||
685 | void __init | 701 | void __init |