]> git.ipfire.org Git - ipfire-2.x.git/blob - src/patches/suse-2.6.27.39/patches.arch/x2APIC_PATCH_42_of_41_77322deb4bc676a5ee645444e7ed1a89f854473d
Imported linux-2.6.27.39 suse/xen patches.
[ipfire-2.x.git] / src / patches / suse-2.6.27.39 / 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 --- a/arch/x86/kernel/apic_64.c
24 +++ b/arch/x86/kernel/apic_64.c
25 @@ -996,7 +996,12 @@ void enable_IR_x2apic(void)
26
27 local_irq_save(flags);
28 mask_8259A();
29 - save_mask_IO_APIC_setup();
30 +
31 + ret = save_mask_IO_APIC_setup();
32 + if (ret) {
33 + printk(KERN_INFO "Saving IO-APIC state failed: %d\n", ret);
34 + goto end;
35 + }
36
37 ret = enable_intr_remapping(1);
38
39 @@ -1006,14 +1011,15 @@ void enable_IR_x2apic(void)
40 }
41
42 if (ret)
43 - goto end;
44 + goto end_restore;
45
46 if (!x2apic) {
47 x2apic = 1;
48 apic_ops = &x2apic_ops;
49 enable_x2apic();
50 }
51 -end:
52 +
53 + end_restore:
54 if (ret)
55 /*
56 * IR enabling failed
57 @@ -1022,6 +1028,7 @@ end:
58 else
59 reinit_intr_remapped_IO_APIC(x2apic_preenabled);
60
61 + end:
62 unmask_8259A();
63 local_irq_restore(flags);
64
65 --- a/arch/x86/kernel/io_apic_64.c
66 +++ b/arch/x86/kernel/io_apic_64.c
67 @@ -474,7 +474,7 @@ int save_mask_IO_APIC_setup(void)
68 kzalloc(sizeof(struct IO_APIC_route_entry) *
69 nr_ioapic_registers[apic], GFP_KERNEL);
70 if (!early_ioapic_entries[apic])
71 - return -ENOMEM;
72 + goto nomem;
73 }
74
75 for (apic = 0; apic < nr_ioapics; apic++)
76 @@ -489,16 +489,31 @@ int save_mask_IO_APIC_setup(void)
77 }
78 }
79 return 0;
80 +
81 + nomem:
82 + for (; apic > 0; apic--)
83 + kfree(early_ioapic_entries[apic]);
84 + kfree(early_ioapic_entries[apic]);
85 + memset(early_ioapic_entries, 0,
86 + ARRAY_SIZE(early_ioapic_entries));
87 +
88 + return -ENOMEM;
89 +
90 }
91
92 void restore_IO_APIC_setup(void)
93 {
94 int apic, pin;
95
96 - for (apic = 0; apic < nr_ioapics; apic++)
97 + for (apic = 0; apic < nr_ioapics; apic++) {
98 + if (!early_ioapic_entries[apic])
99 + break;
100 for (pin = 0; pin < nr_ioapic_registers[apic]; pin++)
101 ioapic_write_entry(apic, pin,
102 early_ioapic_entries[apic][pin]);
103 + kfree(early_ioapic_entries[apic]);
104 + early_ioapic_entries[apic] = NULL;
105 + }
106 }
107
108 void reinit_intr_remapped_IO_APIC(int intr_remapping)