]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blob - src/patches/suse-2.6.27.31/patches.arch/x2APIC_PATCH_42_of_41_77322deb4bc676a5ee645444e7ed1a89f854473d
Merge branch 'master' of git://git.ipfire.org/ipfire-2.x
[people/teissler/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.arch / x2APIC_PATCH_42_of_41_77322deb4bc676a5ee645444e7ed1a89f854473d
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
6
7 Signed-off-by: Thomas Renninger <trenn@suse.de>
8
9 Interrupt remapping could lead to NULL dereference in case of
10 kzalloc failed and memory leak in other way. So fix the
11 both cases.
12
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>
17
18 ---
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(-)
22
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)
28
29 local_irq_save(flags);
30 mask_8259A();
31 - save_mask_IO_APIC_setup();
32 +
33 + ret = save_mask_IO_APIC_setup();
34 + if (ret) {
35 + printk(KERN_INFO "Saving IO-APIC state failed: %d\n", ret);
36 + goto end;
37 + }
38
39 ret = enable_intr_remapping(1);
40
41 @@ -979,14 +984,15 @@ void enable_IR_x2apic(void)
42 }
43
44 if (ret)
45 - goto end;
46 + goto end_restore;
47
48 if (!x2apic) {
49 x2apic = 1;
50 apic_ops = &x2apic_ops;
51 enable_x2apic();
52 }
53 -end:
54 +
55 + end_restore:
56 if (ret)
57 /*
58 * IR enabling failed
59 @@ -995,6 +1001,7 @@ end:
60 else
61 reinit_intr_remapped_IO_APIC(x2apic_preenabled);
62
63 + end:
64 unmask_8259A();
65 local_irq_restore(flags);
66
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])
75 - return -ENOMEM;
76 + goto nomem;
77 }
78
79 for (apic = 0; apic < nr_ioapics; apic++)
80 @@ -489,16 +489,31 @@ int save_mask_IO_APIC_setup(void)
81 }
82 }
83 return 0;
84 +
85 + nomem:
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));
91 +
92 + return -ENOMEM;
93 +
94 }
95
96 void restore_IO_APIC_setup(void)
97 {
98 int apic, pin;
99
100 - for (apic = 0; apic < nr_ioapics; apic++)
101 + for (apic = 0; apic < nr_ioapics; apic++) {
102 + if (!early_ioapic_entries[apic])
103 + break;
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;
109 + }
110 }
111
112 void reinit_intr_remapped_IO_APIC(int intr_remapping)