This sets up the same calling convention from interrupt entry to
KVM interrupt handler for system calls as exists for other interrupt
types.

This is a better API, it uses a save area rather than SPR, and it has
more registers free to use. Using a single common API helps maintain
it, and it becomes easier to use in C in a later patch.

Reviewed-by: Alexey Kardashevskiy <a...@ozlabs.ru>
Signed-off-by: Nicholas Piggin <npig...@gmail.com>
---
 arch/powerpc/kernel/exceptions-64s.S | 21 +++++++++++++++-
 arch/powerpc/kvm/book3s_64_entry.S   | 37 +++++++++-------------------
 2 files changed, 32 insertions(+), 26 deletions(-)

diff --git a/arch/powerpc/kernel/exceptions-64s.S 
b/arch/powerpc/kernel/exceptions-64s.S
index 115cf79f3e82..4615057681c3 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -1892,8 +1892,27 @@ EXC_VIRT_END(system_call, 0x4c00, 0x100)
 
 #ifdef CONFIG_KVM_BOOK3S_64_HANDLER
 TRAMP_REAL_BEGIN(kvm_hcall)
+       std     r9,PACA_EXGEN+EX_R9(r13)
+       std     r11,PACA_EXGEN+EX_R11(r13)
+       std     r12,PACA_EXGEN+EX_R12(r13)
+       mfcr    r9
        mfctr   r10
-       SET_SCRATCH0(r10) /* Save r13 in SCRATCH0 */
+       std     r10,PACA_EXGEN+EX_R13(r13)
+       li      r10,0
+       std     r10,PACA_EXGEN+EX_CFAR(r13)
+       std     r10,PACA_EXGEN+EX_CTR(r13)
+        /*
+         * Save the PPR (on systems that support it) before changing to
+         * HMT_MEDIUM. That allows the KVM code to save that value into the
+         * guest state (it is the guest's PPR value).
+         */
+BEGIN_FTR_SECTION
+       mfspr   r10,SPRN_PPR
+       std     r10,PACA_EXGEN+EX_PPR(r13)
+END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
+
+       HMT_MEDIUM
+
 #ifdef CONFIG_RELOCATABLE
        /*
         * Requires __LOAD_FAR_HANDLER beause kvmppc_hcall lives
diff --git a/arch/powerpc/kvm/book3s_64_entry.S 
b/arch/powerpc/kvm/book3s_64_entry.S
index b6149df21de3..de81ab69555b 100644
--- a/arch/powerpc/kvm/book3s_64_entry.S
+++ b/arch/powerpc/kvm/book3s_64_entry.S
@@ -11,33 +11,21 @@
  * These are 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.
  */
+
+/*
+ * This is a hcall, so guest register call convention is as
+ * Documentation/powerpc/papr_hcalls.rst.
+ *
+ * The state of registers is as below, except CFAR is not saved, R13 is not
+ * in SCRATCH0, and R10 does not contain the trap.
+ */
 .global        kvmppc_hcall
 .balign IFETCH_ALIGN_BYTES
 kvmppc_hcall:
-       /*
-        * This is a hcall, so register convention is as
-        * Documentation/powerpc/papr_hcalls.rst, with these additions:
-        * R13          = PACA
-        * guest R13 saved in SPRN_SCRATCH0
-        * R10          = free
-        * guest r10 saved in PACA_EXGEN
-        */
-        /*
-         * Save the PPR (on systems that support it) before changing to
-         * HMT_MEDIUM. That allows the KVM code to save that value into the
-         * guest state (it is the guest's PPR value).
-         */
-BEGIN_FTR_SECTION
-       mfspr   r10,SPRN_PPR
-       std     r10,HSTATE_PPR(r13)
-END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
-       HMT_MEDIUM
-       mfcr    r10
-       std     r12,HSTATE_SCRATCH0(r13)
-       sldi    r12,r10,32
-       ori     r12,r12,0xc00
-       ld      r10,PACA_EXGEN+EX_R10(r13)
-       b       do_kvm_interrupt
+       ld      r10,PACA_EXGEN+EX_R13(r13)
+       SET_SCRATCH0(r10)
+       li      r10,0xc00
+       /* Now we look like kvmppc_interrupt */
 
 /*
  * KVM interrupt entry occurs after GEN_INT_ENTRY runs, and follows that
@@ -84,7 +72,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
        ld      r10,EX_R10(r11)
        ld      r11,EX_R11(r11)
 
-do_kvm_interrupt:
        /*
         * Hcalls and other interrupts come here after normalising register
         * contents and save locations:
-- 
2.23.0

Reply via email to