diff options
author | Cyrill Gorcunov <gorcunov@gmail.com> | 2008-09-18 15:37:57 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-10-16 10:53:11 -0400 |
commit | 5ffa4eb2224343ec3fbd492ffe71e28e797435b7 (patch) | |
tree | 728cd604177a5d4f392ef3f5290af37f06c8b033 /arch/x86/kernel/io_apic.c | |
parent | 2976fe20125587c944c8df48d991c38f0891fb28 (diff) |
x86: io-apic - interrupt remapping fix
Interrupt remapping could lead to NULL dereference in case of
kzalloc failed and memory leak in other way. So fix the
both cases.
Signed-off-by: Cyrill Gorcunov <gorcunov@gmail.com>
Cc: "Maciej W. Rozycki" <macro@linux-mips.org>
Cc: Suresh Siddha <suresh.b.siddha@intel.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/io_apic.c')
-rw-r--r-- | arch/x86/kernel/io_apic.c | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/arch/x86/kernel/io_apic.c b/arch/x86/kernel/io_apic.c index 01419fdc1d5d..4cc9cb64c811 100644 --- a/arch/x86/kernel/io_apic.c +++ b/arch/x86/kernel/io_apic.c | |||
@@ -812,7 +812,7 @@ int save_mask_IO_APIC_setup(void) | |||
812 | kzalloc(sizeof(struct IO_APIC_route_entry) * | 812 | kzalloc(sizeof(struct IO_APIC_route_entry) * |
813 | nr_ioapic_registers[apic], GFP_KERNEL); | 813 | nr_ioapic_registers[apic], GFP_KERNEL); |
814 | if (!early_ioapic_entries[apic]) | 814 | if (!early_ioapic_entries[apic]) |
815 | return -ENOMEM; | 815 | goto nomem; |
816 | } | 816 | } |
817 | 817 | ||
818 | for (apic = 0; apic < nr_ioapics; apic++) | 818 | for (apic = 0; apic < nr_ioapics; apic++) |
@@ -826,17 +826,32 @@ int save_mask_IO_APIC_setup(void) | |||
826 | ioapic_write_entry(apic, pin, entry); | 826 | ioapic_write_entry(apic, pin, entry); |
827 | } | 827 | } |
828 | } | 828 | } |
829 | |||
829 | return 0; | 830 | return 0; |
831 | |||
832 | nomem: | ||
833 | for (; apic > 0; apic--) | ||
834 | kfree(early_ioapic_entries[apic]); | ||
835 | kfree(early_ioapic_entries[apic]); | ||
836 | memset(early_ioapic_entries, 0, | ||
837 | ARRAY_SIZE(early_ioapic_entries)); | ||
838 | |||
839 | return -ENOMEM; | ||
830 | } | 840 | } |
831 | 841 | ||
832 | void restore_IO_APIC_setup(void) | 842 | void restore_IO_APIC_setup(void) |
833 | { | 843 | { |
834 | int apic, pin; | 844 | int apic, pin; |
835 | 845 | ||
836 | for (apic = 0; apic < nr_ioapics; apic++) | 846 | for (apic = 0; apic < nr_ioapics; apic++) { |
847 | if (!early_ioapic_entries[apic]) | ||
848 | break; | ||
837 | for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) | 849 | for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) |
838 | ioapic_write_entry(apic, pin, | 850 | ioapic_write_entry(apic, pin, |
839 | early_ioapic_entries[apic][pin]); | 851 | early_ioapic_entries[apic][pin]); |
852 | kfree(early_ioapic_entries[apic]); | ||
853 | early_ioapic_entries[apic] = NULL; | ||
854 | } | ||
840 | } | 855 | } |
841 | 856 | ||
842 | void reinit_intr_remapped_IO_APIC(int intr_remapping) | 857 | void reinit_intr_remapped_IO_APIC(int intr_remapping) |