aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/mpparse.c
diff options
context:
space:
mode:
authorYinghai Lu <yinghai@kernel.org>2009-05-06 13:07:07 -0400
committerIngo Molnar <mingo@elte.hu>2009-05-11 04:35:07 -0400
commitee214558c2e959781a406e76c5b34364da638e1d (patch)
tree5fc0218815773b7eba93c91dc9e1972bf4f43954 /arch/x86/kernel/mpparse.c
parentb9e0353fc85dab4ef5ebcef2bd09ebc4ce6d5a7b (diff)
x86: fix alloc_mptable()
Fix the conditions when we stop updating the mptable due to running out of slots. [ Impact: fix memory corruption / non-working update_mptable boot parameter ] Signed-off-by: Yinghai Lu <yinghai@kernel.org> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Jesse Barnes <jbarnes@virtuousgeek.org> Cc: Len Brown <lenb@kernel.org> LKML-Reference: <4A01C3BB.1000609@kernel.org> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/mpparse.c')
-rw-r--r--arch/x86/kernel/mpparse.c25
1 files changed, 9 insertions, 16 deletions
diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c
index 70fd7e414c15..cd2a41a7c45c 100644
--- a/arch/x86/kernel/mpparse.c
+++ b/arch/x86/kernel/mpparse.c
@@ -870,24 +870,17 @@ static
870inline void __init check_irq_src(struct mpc_intsrc *m, int *nr_m_spare) {} 870inline void __init check_irq_src(struct mpc_intsrc *m, int *nr_m_spare) {}
871#endif /* CONFIG_X86_IO_APIC */ 871#endif /* CONFIG_X86_IO_APIC */
872 872
873static int check_slot(unsigned long mpc_new_phys, unsigned long mpc_new_length, 873static int
874 int count) 874check_slot(unsigned long mpc_new_phys, unsigned long mpc_new_length, int count)
875{ 875{
876 if (!mpc_new_phys) { 876 int ret = 0;
877 pr_info("No spare slots, try to append...take your risk, " 877
878 "new mpc_length %x\n", count); 878 if (!mpc_new_phys || count <= mpc_new_length) {
879 } else { 879 WARN(1, "update_mptable: No spare slots (length: %x)\n", count);
880 if (count <= mpc_new_length) 880 return -1;
881 pr_info("No spare slots, try to append..., "
882 "new mpc_length %x\n", count);
883 else {
884 pr_err("mpc_new_length %lx is too small\n",
885 mpc_new_length);
886 return -1;
887 }
888 } 881 }
889 882
890 return 0; 883 return ret;
891} 884}
892 885
893static int __init replace_intsrc_all(struct mpc_table *mpc, 886static int __init replace_intsrc_all(struct mpc_table *mpc,
@@ -946,7 +939,7 @@ static int __init replace_intsrc_all(struct mpc_table *mpc,
946 } else { 939 } else {
947 struct mpc_intsrc *m = (struct mpc_intsrc *)mpt; 940 struct mpc_intsrc *m = (struct mpc_intsrc *)mpt;
948 count += sizeof(struct mpc_intsrc); 941 count += sizeof(struct mpc_intsrc);
949 if (!check_slot(mpc_new_phys, mpc_new_length, count)) 942 if (check_slot(mpc_new_phys, mpc_new_length, count) < 0)
950 goto out; 943 goto out;
951 assign_to_mpc_intsrc(&mp_irqs[i], m); 944 assign_to_mpc_intsrc(&mp_irqs[i], m);
952 mpc->length = count; 945 mpc->length = count;