1 From: Cyrill Gorcunov <gorcunov@gmail.com>
2 Subject: x86: io-apic - interrupt remapping fix
3 References: fate #303948 and fate #303984
4 Patch-Mainline: queued for .28
5 Commit-ID: 77322deb4bc676a5ee645444e7ed1a89f854473d
7 Signed-off-by: Thomas Renninger <trenn@suse.de>
9 Interrupt remapping could lead to NULL dereference in case of
10 kzalloc failed and memory leak in other way. So fix the
13 Signed-off-by: Cyrill Gorcunov <gorcunov@gmail.com>
14 Cc: "Maciej W. Rozycki" <macro@linux-mips.org>
15 Cc: Suresh Siddha <suresh.b.siddha@intel.com>
16 Signed-off-by: Ingo Molnar <mingo@elte.hu>
19 arch/x86/kernel/apic_64.c | 13 ++++++++++---
20 arch/x86/kernel/io_apic_64.c | 19 +++++++++++++++++--
21 2 files changed, 27 insertions(+), 5 deletions(-)
23 Index: linux-2.6.26/arch/x86/kernel/apic_64.c
24 ===================================================================
25 --- linux-2.6.26.orig/arch/x86/kernel/apic_64.c
26 +++ linux-2.6.26/arch/x86/kernel/apic_64.c
27 @@ -969,7 +969,12 @@ void enable_IR_x2apic(void)
29 local_irq_save(flags);
31 - save_mask_IO_APIC_setup();
33 + ret = save_mask_IO_APIC_setup();
35 + printk(KERN_INFO "Saving IO-APIC state failed: %d\n", ret);
39 ret = enable_intr_remapping(1);
41 @@ -979,14 +984,15 @@ void enable_IR_x2apic(void)
50 apic_ops = &x2apic_ops;
59 @@ -995,6 +1001,7 @@ end:
61 reinit_intr_remapped_IO_APIC(x2apic_preenabled);
65 local_irq_restore(flags);
67 Index: linux-2.6.26/arch/x86/kernel/io_apic_64.c
68 ===================================================================
69 --- linux-2.6.26.orig/arch/x86/kernel/io_apic_64.c
70 +++ linux-2.6.26/arch/x86/kernel/io_apic_64.c
71 @@ -474,7 +474,7 @@ int save_mask_IO_APIC_setup(void)
72 kzalloc(sizeof(struct IO_APIC_route_entry) *
73 nr_ioapic_registers[apic], GFP_KERNEL);
74 if (!early_ioapic_entries[apic])
79 for (apic = 0; apic < nr_ioapics; apic++)
80 @@ -489,16 +489,31 @@ int save_mask_IO_APIC_setup(void)
86 + for (; apic > 0; apic--)
87 + kfree(early_ioapic_entries[apic]);
88 + kfree(early_ioapic_entries[apic]);
89 + memset(early_ioapic_entries, 0,
90 + ARRAY_SIZE(early_ioapic_entries));
96 void restore_IO_APIC_setup(void)
100 - for (apic = 0; apic < nr_ioapics; apic++)
101 + for (apic = 0; apic < nr_ioapics; apic++) {
102 + if (!early_ioapic_entries[apic])
104 for (pin = 0; pin < nr_ioapic_registers[apic]; pin++)
105 ioapic_write_entry(apic, pin,
106 early_ioapic_entries[apic][pin]);
107 + kfree(early_ioapic_entries[apic]);
108 + early_ioapic_entries[apic] = NULL;
112 void reinit_intr_remapped_IO_APIC(int intr_remapping)