KVM: PPC: Book3S 64: move KVM interrupt entry to a common entry point
authorNicholas Piggin <npiggin@gmail.com>
Fri, 28 May 2021 09:07:21 +0000 (19:07 +1000)
committerMichael Ellerman <mpe@ellerman.id.au>
Thu, 10 Jun 2021 12:12:01 +0000 (22:12 +1000)
Rather than bifurcate the call depending on whether or not HV is
possible, and have the HV entry test for PR, just make a single
common point which does the demultiplexing. This makes it simpler
to add another type of exit handler.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Reviewed-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Fabiano Rosas <farosas@linux.ibm.com>
Acked-by: Paul Mackerras <paulus@ozlabs.org>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20210528090752.3542186-2-npiggin@gmail.com
arch/powerpc/kernel/exceptions-64s.S
arch/powerpc/kvm/Makefile
arch/powerpc/kvm/book3s_64_entry.S [new file with mode: 0644]
arch/powerpc/kvm/book3s_hv_rmhandlers.S

index fa8e52a..868077f 100644 (file)
@@ -208,7 +208,6 @@ do_define_int n
 .endm
 
 #ifdef CONFIG_KVM_BOOK3S_64_HANDLER
-#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
 /*
  * All interrupts which set HSRR registers, as well as SRESET and MCE and
  * syscall when invoked with "sc 1" switch to MSR[HV]=1 (HVMODE) to be taken,
@@ -238,13 +237,8 @@ do_define_int n
 
 /*
  * If an interrupt is taken while a guest is running, it is immediately routed
- * to KVM to handle. If both HV and PR KVM arepossible, KVM interrupts go first
- * to kvmppc_interrupt_hv, which handles the PR guest case.
+ * to KVM to handle.
  */
-#define kvmppc_interrupt kvmppc_interrupt_hv
-#else
-#define kvmppc_interrupt kvmppc_interrupt_pr
-#endif
 
 .macro KVMTEST name
        lbz     r10,HSTATE_IN_GUEST(r13)
index 2bfeaa1..bbc071a 100644 (file)
@@ -57,6 +57,7 @@ kvm-pr-y := \
        book3s_32_mmu.o
 
 kvm-book3s_64-builtin-objs-$(CONFIG_KVM_BOOK3S_64_HANDLER) += \
+       book3s_64_entry.o \
        tm.o
 
 ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE
diff --git a/arch/powerpc/kvm/book3s_64_entry.S b/arch/powerpc/kvm/book3s_64_entry.S
new file mode 100644 (file)
index 0000000..7a039ea
--- /dev/null
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#include <asm/asm-offsets.h>
+#include <asm/cache.h>
+#include <asm/kvm_asm.h>
+#include <asm/kvm_book3s_asm.h>
+#include <asm/ppc_asm.h>
+#include <asm/reg.h>
+
+/*
+ * This is branched to from interrupt handlers in exception-64s.S which set
+ * IKVM_REAL or IKVM_VIRT, if HSTATE_IN_GUEST was found to be non-zero.
+ */
+.global        kvmppc_interrupt
+.balign IFETCH_ALIGN_BYTES
+kvmppc_interrupt:
+       /*
+        * Register contents:
+        * R12          = (guest CR << 32) | interrupt vector
+        * R13          = PACA
+        * guest R12 saved in shadow VCPU SCRATCH0
+        * guest R13 saved in SPRN_SCRATCH0
+        */
+#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
+       std     r9,HSTATE_SCRATCH2(r13)
+       lbz     r9,HSTATE_IN_GUEST(r13)
+       cmpwi   r9,KVM_GUEST_MODE_HOST_HV
+       beq     kvmppc_bad_host_intr
+#ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE
+       cmpwi   r9,KVM_GUEST_MODE_GUEST
+       ld      r9,HSTATE_SCRATCH2(r13)
+       beq     kvmppc_interrupt_pr
+#endif
+       b       kvmppc_interrupt_hv
+#else
+       b       kvmppc_interrupt_pr
+#endif
index 004f0d4..a28b41b 100644 (file)
@@ -1272,16 +1272,8 @@ kvmppc_interrupt_hv:
         * R13          = PACA
         * guest R12 saved in shadow VCPU SCRATCH0
         * guest R13 saved in SPRN_SCRATCH0
+        * guest R9 saved in HSTATE_SCRATCH2
         */
-       std     r9, HSTATE_SCRATCH2(r13)
-       lbz     r9, HSTATE_IN_GUEST(r13)
-       cmpwi   r9, KVM_GUEST_MODE_HOST_HV
-       beq     kvmppc_bad_host_intr
-#ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE
-       cmpwi   r9, KVM_GUEST_MODE_GUEST
-       ld      r9, HSTATE_SCRATCH2(r13)
-       beq     kvmppc_interrupt_pr
-#endif
        /* We're now back in the host but in guest MMU context */
        li      r9, KVM_GUEST_MODE_HOST_HV
        stb     r9, HSTATE_IN_GUEST(r13)
@@ -3287,6 +3279,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_P9_TM_HV_ASSIST)
  * cfar is saved in HSTATE_CFAR(r13)
  * ppr is saved in HSTATE_PPR(r13)
  */
+.global kvmppc_bad_host_intr
 kvmppc_bad_host_intr:
        /*
         * Switch to the emergency stack, but start half-way down in