]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/4.4.13/powerpc-book3s64-fix-branching-to-ool-handlers-in-relocatable-kernel.patch
4.9-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 4.4.13 / powerpc-book3s64-fix-branching-to-ool-handlers-in-relocatable-kernel.patch
CommitLineData
b91494dd
GKH
1From 8ed8ab40047a570fdd8043a40c104a57248dd3fd Mon Sep 17 00:00:00 2001
2From: Hari Bathini <hbathini@linux.vnet.ibm.com>
3Date: Fri, 15 Apr 2016 22:48:02 +1000
4Subject: powerpc/book3s64: Fix branching to OOL handlers in relocatable kernel
5
6From: Hari Bathini <hbathini@linux.vnet.ibm.com>
7
8commit 8ed8ab40047a570fdd8043a40c104a57248dd3fd upstream.
9
10Some of the interrupt vectors on 64-bit POWER server processors are only
1132 bytes long (8 instructions), which is not enough for the full
12first-level interrupt handler. For these we need to branch to an
13out-of-line (OOL) handler. But when we are running a relocatable kernel,
14interrupt vectors till __end_interrupts marker are copied down to real
15address 0x100. So, branching to labels (ie. OOL handlers) outside this
16section must be handled differently (see LOAD_HANDLER()), considering
17relocatable kernel, which would need at least 4 instructions.
18
19However, branching from interrupt vector means that we corrupt the
20CFAR (come-from address register) on POWER7 and later processors as
21mentioned in commit 1707dd16. So, EXCEPTION_PROLOG_0 (6 instructions)
22that contains the part up to the point where the CFAR is saved in the
23PACA should be part of the short interrupt vectors before we branch out
24to OOL handlers.
25
26But as mentioned already, there are interrupt vectors on 64-bit POWER
27server processors that are only 32 bytes long (like vectors 0x4f00,
280x4f20, etc.), which cannot accomodate the above two cases at the same
29time owing to space constraint. Currently, in these interrupt vectors,
30we simply branch out to OOL handlers, without using LOAD_HANDLER(),
31which leaves us vulnerable when running a relocatable kernel (eg. kdump
32case). While this has been the case for sometime now and kdump is used
33widely, we were fortunate not to see any problems so far, for three
34reasons:
35
36 1. In almost all cases, production kernel (relocatable) is used for
37 kdump as well, which would mean that crashed kernel's OOL handler
38 would be at the same place where we end up branching to, from short
39 interrupt vector of kdump kernel.
40 2. Also, OOL handler was unlikely the reason for crash in almost all
41 the kdump scenarios, which meant we had a sane OOL handler from
42 crashed kernel that we branched to.
43 3. On most 64-bit POWER server processors, page size is large enough
44 that marking interrupt vector code as executable (see commit
45 429d2e83) leads to marking OOL handler code from crashed kernel,
46 that sits right below interrupt vector code from kdump kernel, as
47 executable as well.
48
49Let us fix this by moving the __end_interrupts marker down past OOL
50handlers to make sure that we also copy OOL handlers to real address
510x100 when running a relocatable kernel.
52
53This fix has been tested successfully in kdump scenario, on an LPAR with
544K page size by using different default/production kernel and kdump
55kernel.
56
57Also tested by manually corrupting the OOL handlers in the first kernel
58and then kdump'ing, and then causing the OOL handlers to fire - mpe.
59
60Fixes: c1fb6816fb1b ("powerpc: Add relocation on exception vector handlers")
61Signed-off-by: Hari Bathini <hbathini@linux.vnet.ibm.com>
62Signed-off-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
63Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
64Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
65
66---
67 arch/powerpc/kernel/exceptions-64s.S | 16 +++++++++++-----
68 1 file changed, 11 insertions(+), 5 deletions(-)
69
70--- a/arch/powerpc/kernel/exceptions-64s.S
71+++ b/arch/powerpc/kernel/exceptions-64s.S
72@@ -962,11 +962,6 @@ hv_facility_unavailable_relon_trampoline
73 #endif
74 STD_RELON_EXCEPTION_PSERIES(0x5700, 0x1700, altivec_assist)
75
76- /* Other future vectors */
77- .align 7
78- .globl __end_interrupts
79-__end_interrupts:
80-
81 .align 7
82 system_call_entry:
83 b system_call_common
84@@ -1253,6 +1248,17 @@ __end_handlers:
85 STD_RELON_EXCEPTION_PSERIES_OOL(0xf60, facility_unavailable)
86 STD_RELON_EXCEPTION_HV_OOL(0xf80, hv_facility_unavailable)
87
88+ /*
89+ * The __end_interrupts marker must be past the out-of-line (OOL)
90+ * handlers, so that they are copied to real address 0x100 when running
91+ * a relocatable kernel. This ensures they can be reached from the short
92+ * trampoline handlers (like 0x4f00, 0x4f20, etc.) which branch
93+ * directly, without using LOAD_HANDLER().
94+ */
95+ .align 7
96+ .globl __end_interrupts
97+__end_interrupts:
98+
99 #if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV)
100 /*
101 * Data area reserved for FWNMI option.