diff options
| -rw-r--r-- | arch/x86_64/kernel/mpparse.c | 37 |
1 files changed, 19 insertions, 18 deletions
diff --git a/arch/x86_64/kernel/mpparse.c b/arch/x86_64/kernel/mpparse.c index 20e88f4b564b..b8d53dfa9931 100644 --- a/arch/x86_64/kernel/mpparse.c +++ b/arch/x86_64/kernel/mpparse.c | |||
| @@ -152,6 +152,21 @@ static void __init MP_bus_info (struct mpc_config_bus *m) | |||
| 152 | } | 152 | } |
| 153 | } | 153 | } |
| 154 | 154 | ||
| 155 | static int bad_ioapic(unsigned long address) | ||
| 156 | { | ||
| 157 | if (nr_ioapics >= MAX_IO_APICS) { | ||
| 158 | printk(KERN_ERR "ERROR: Max # of I/O APICs (%d) exceeded " | ||
| 159 | "(found %d)\n", MAX_IO_APICS, nr_ioapics); | ||
| 160 | panic("Recompile kernel with bigger MAX_IO_APICS!\n"); | ||
| 161 | } | ||
| 162 | if (!address) { | ||
| 163 | printk(KERN_ERR "WARNING: Bogus (zero) I/O APIC address" | ||
| 164 | " found in table, skipping!\n"); | ||
| 165 | return 1; | ||
| 166 | } | ||
| 167 | return 0; | ||
| 168 | } | ||
| 169 | |||
| 155 | static void __init MP_ioapic_info (struct mpc_config_ioapic *m) | 170 | static void __init MP_ioapic_info (struct mpc_config_ioapic *m) |
| 156 | { | 171 | { |
| 157 | if (!(m->mpc_flags & MPC_APIC_USABLE)) | 172 | if (!(m->mpc_flags & MPC_APIC_USABLE)) |
| @@ -159,16 +174,10 @@ static void __init MP_ioapic_info (struct mpc_config_ioapic *m) | |||
| 159 | 174 | ||
| 160 | printk("I/O APIC #%d at 0x%X.\n", | 175 | printk("I/O APIC #%d at 0x%X.\n", |
| 161 | m->mpc_apicid, m->mpc_apicaddr); | 176 | m->mpc_apicid, m->mpc_apicaddr); |
| 162 | if (nr_ioapics >= MAX_IO_APICS) { | 177 | |
| 163 | printk(KERN_ERR "Max # of I/O APICs (%d) exceeded (found %d).\n", | 178 | if (bad_ioapic(m->mpc_apicaddr)) |
| 164 | MAX_IO_APICS, nr_ioapics); | ||
| 165 | panic("Recompile kernel with bigger MAX_IO_APICS!.\n"); | ||
| 166 | } | ||
| 167 | if (!m->mpc_apicaddr) { | ||
| 168 | printk(KERN_ERR "WARNING: bogus zero I/O APIC address" | ||
| 169 | " found in MP table, skipping!\n"); | ||
| 170 | return; | 179 | return; |
| 171 | } | 180 | |
| 172 | mp_ioapics[nr_ioapics] = *m; | 181 | mp_ioapics[nr_ioapics] = *m; |
| 173 | nr_ioapics++; | 182 | nr_ioapics++; |
| 174 | } | 183 | } |
| @@ -647,16 +656,8 @@ void __init mp_register_ioapic(u8 id, u32 address, u32 gsi_base) | |||
| 647 | { | 656 | { |
| 648 | int idx = 0; | 657 | int idx = 0; |
| 649 | 658 | ||
| 650 | if (nr_ioapics >= MAX_IO_APICS) { | 659 | if (bad_ioapic(address)) |
| 651 | printk(KERN_ERR "ERROR: Max # of I/O APICs (%d) exceeded " | ||
| 652 | "(found %d)\n", MAX_IO_APICS, nr_ioapics); | ||
| 653 | panic("Recompile kernel with bigger MAX_IO_APICS!\n"); | ||
| 654 | } | ||
| 655 | if (!address) { | ||
| 656 | printk(KERN_ERR "WARNING: Bogus (zero) I/O APIC address" | ||
| 657 | " found in MADT table, skipping!\n"); | ||
| 658 | return; | 660 | return; |
| 659 | } | ||
| 660 | 661 | ||
| 661 | idx = nr_ioapics++; | 662 | idx = nr_ioapics++; |
| 662 | 663 | ||
