aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kvm/book3s_segment.S
diff options
context:
space:
mode:
authorNicholas Piggin <npiggin@gmail.com>2017-01-27 14:00:34 +1000
committerMichael Ellerman <mpe@ellerman.id.au>2017-01-31 19:07:39 +1100
commita97a65d53d9f53b6897dc1b2aed381bc1707136b (patch)
tree08dcf2d0b98a978d80bf09dc5f6829e9831c7bb5 /arch/powerpc/kvm/book3s_segment.S
parentKVM: PPC: Book3S: Move 64-bit KVM interrupt handler out from alt section (diff)
downloadlinux-dev-a97a65d53d9f53b6897dc1b2aed381bc1707136b.tar.xz
linux-dev-a97a65d53d9f53b6897dc1b2aed381bc1707136b.zip
KVM: PPC: Book3S: 64-bit CONFIG_RELOCATABLE support for interrupts
64-bit Book3S exception handlers must find the dynamic kernel base to add to the target address when branching beyond __end_interrupts, in order to support kernel running at non-0 physical address. Support this in KVM by branching with CTR, similarly to regular interrupt handlers. The guest CTR saved in HSTATE_SCRATCH1 and restored after the branch. Without this, the host kernel hangs and crashes randomly when it is running at a non-0 address and a KVM guest is started. Signed-off-by: Nicholas Piggin <npiggin@gmail.com> Acked-by: Paul Mackerras <paulus@ozlabs.org> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Diffstat (limited to 'arch/powerpc/kvm/book3s_segment.S')
-rw-r--r--arch/powerpc/kvm/book3s_segment.S7
1 files changed, 7 insertions, 0 deletions
diff --git a/arch/powerpc/kvm/book3s_segment.S b/arch/powerpc/kvm/book3s_segment.S
index 68e45080cf93..2a2b96d53999 100644
--- a/arch/powerpc/kvm/book3s_segment.S
+++ b/arch/powerpc/kvm/book3s_segment.S
@@ -175,9 +175,16 @@ kvmppc_interrupt_pr:
* R12 = (guest CR << 32) | exit handler id
* R13 = PACA
* HSTATE.SCRATCH0 = guest R12
+ * HSTATE.SCRATCH1 = guest CTR if RELOCATABLE
*/
#ifdef CONFIG_PPC64
/* Match 32-bit entry */
+#ifdef CONFIG_RELOCATABLE
+ std r9, HSTATE_SCRATCH2(r13)
+ ld r9, HSTATE_SCRATCH1(r13)
+ mtctr r9
+ ld r9, HSTATE_SCRATCH2(r13)
+#endif
rotldi r12, r12, 32 /* Flip R12 halves for stw */
stw r12, HSTATE_SCRATCH1(r13) /* CR is now in the low half */
srdi r12, r12, 32 /* shift trap into low half */