]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - src/patches/suse-2.6.27.39/patches.arch/ppc-xics-EOI-unmapped-irqs.patch
Fix oinkmaster patch.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.39 / patches.arch / ppc-xics-EOI-unmapped-irqs.patch
CommitLineData
2cb7cef9
BS
1From: Milton Miller <miltonm@bga.com>
2Subject: powerpc/xics: EOI unmapped irqs after disabling them
3Date: Fri Oct 10 01:56:23 2008 +0000
4X-Git-Tag: v2.6.28-rc1~569^2~27
5X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=8767e9badca7cdf0adc2564d7524092d47ababf3
6Patch-mainline: v2.6.28-rc1
7References: bnc#459065
8
9When reciving an irq vector that does not have a linux mapping, the kernel
10prints a message and calls RTAS to disable the irq source. Previously
11the kernel did not EOI the interrupt, causing the source to think it is
12still being processed by software. While this does add an additional
13layer of protection against interrupt storms had RTAS failed to disable
14the source, it also prevents the interrupt from working when a driver
15later enables it. (We could alternatively send an EOI on startup, but
16that strategy would likely fail on an emulated xics.)
17
18All interrupts should be disabled when the kernel starts, but this can
19be observed if a driver does not shutdown an interrupt in its reboot
20hook before starting a new kernel with kexec.
21
22Michael reports this can be reproduced trivially by banging the keyboard
23while kexec'ing on a P5 LPAR: even though the hvc_console driver request's
24the console irq later in boot, the console is non-functional because
25we're receiving no console interrupts.
26
27Reported-By: Michael Ellerman
28Signed-off-by: Milton Miller <miltonm@bga.com>
29Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
30Acked-by: Petr Tesarik <ptesarik@suse.cz>
31
32---
33 arch/powerpc/platforms/pseries/xics.c | 53 ++++++++++++++++++++++++++--------
34 1 file changed, 41 insertions(+), 12 deletions(-)
35
36--- linux-2.6.27-SLE11_BRANCH.orig/arch/powerpc/platforms/pseries/xics.c 2009-04-16 10:33:47.000000000 +0200
37+++ linux-2.6.27-SLE11_BRANCH/arch/powerpc/platforms/pseries/xics.c 2009-04-16 10:52:29.000000000 +0200
38@@ -335,32 +335,61 @@ static void xics_eoi_lpar(unsigned int v
39 lpar_xirr_info_set((0xff << 24) | irq);
40 }
41
42-static inline unsigned int xics_remap_irq(unsigned int vec)
43+static inline unsigned int xics_xirr_vector(unsigned int xirr)
44 {
45- unsigned int irq;
46+ /*
47+ * The top byte is the old cppr, to be restored on EOI.
48+ * The remaining 24 bits are the vector.
49+ */
50+ return xirr & 0x00ffffff;
51+}
52
53- vec &= 0x00ffffff;
54+static void xics_mask_unknown_vec(unsigned int vec)
55+{
56+ printk(KERN_ERR "Interrupt %u (real) is invalid, disabling it.\n", vec);
57+ xics_mask_real_irq(vec);
58+}
59+
60+static unsigned int xics_get_irq_direct(void)
61+{
62+ unsigned int xirr = direct_xirr_info_get();
63+ unsigned int vec = xics_xirr_vector(xirr);
64+ unsigned int irq;
65
66 if (vec == XICS_IRQ_SPURIOUS)
67 return NO_IRQ;
68+
69 irq = irq_radix_revmap(xics_host, vec);
70 if (likely(irq != NO_IRQ))
71 return irq;
72
73- printk(KERN_ERR "Interrupt %u (real) is invalid,"
74- " disabling it.\n", vec);
75- xics_mask_real_irq(vec);
76- return NO_IRQ;
77-}
78+ /* We don't have a linux mapping, so have rtas mask it. */
79+ xics_mask_unknown_vec(vec);
80
81-static unsigned int xics_get_irq_direct(void)
82-{
83- return xics_remap_irq(direct_xirr_info_get());
84+ /* We might learn about it later, so EOI it */
85+ direct_xirr_info_set(xirr);
86+ return NO_IRQ;
87 }
88
89 static unsigned int xics_get_irq_lpar(void)
90 {
91- return xics_remap_irq(lpar_xirr_info_get());
92+ unsigned int xirr = lpar_xirr_info_get();
93+ unsigned int vec = xics_xirr_vector(xirr);
94+ unsigned int irq;
95+
96+ if (vec == XICS_IRQ_SPURIOUS)
97+ return NO_IRQ;
98+
99+ irq = irq_radix_revmap(xics_host, vec);
100+ if (likely(irq != NO_IRQ))
101+ return irq;
102+
103+ /* We don't have a linux mapping, so have RTAS mask it. */
104+ xics_mask_unknown_vec(vec);
105+
106+ /* We might learn about it later, so EOI it */
107+ lpar_xirr_info_set(xirr);
108+ return NO_IRQ;
109 }
110
111 #ifdef CONFIG_SMP