diff options
author | Yinghai Lu <yinghai@kernel.org> | 2009-05-06 13:07:07 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-05-11 04:35:07 -0400 |
commit | ee214558c2e959781a406e76c5b34364da638e1d (patch) | |
tree | 5fc0218815773b7eba93c91dc9e1972bf4f43954 /arch/x86/kernel/mpparse.c | |
parent | b9e0353fc85dab4ef5ebcef2bd09ebc4ce6d5a7b (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.c | 25 |
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 | |||
870 | inline void __init check_irq_src(struct mpc_intsrc *m, int *nr_m_spare) {} | 870 | inline 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 | ||
873 | static int check_slot(unsigned long mpc_new_phys, unsigned long mpc_new_length, | 873 | static int |
874 | int count) | 874 | check_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 | ||
893 | static int __init replace_intsrc_all(struct mpc_table *mpc, | 886 | static 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; |