]> git.baikalelectronics.ru Git - kernel.git/commitdiff
KVM: PPC: Book3S 64: Minimise hcall handler calling convention differences
authorNicholas Piggin <npiggin@gmail.com>
Fri, 28 May 2021 09:07:27 +0000 (19:07 +1000)
committerMichael Ellerman <mpe@ellerman.id.au>
Thu, 10 Jun 2021 12:12:12 +0000 (22:12 +1000)
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.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Reviewed-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20210528090752.3542186-8-npiggin@gmail.com
arch/powerpc/kernel/exceptions-64s.S
arch/powerpc/kvm/book3s_64_entry.S

index bf377bfeeb1a4b82034f97614baf7d22cc47c65e..f7fc6e078d4edbc6c97df76830c7e459e6e10588 100644 (file)
@@ -1869,8 +1869,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
index 66170ea85bc2a7ee157a94b2ee95bbd6a7a70aa2..a01046202eef4c512d6e4d26a601549dd457cf58 100644 (file)
  * 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 register convention is as
+ * Documentation/powerpc/papr_hcalls.rst.
+ *
+ * This may also be a syscall from PR-KVM userspace that is to be
+ * reflected to the PR guest kernel, so registers may be set up for
+ * a system call rather than hcall. We don't currently clobber
+ * anything here, but the 0xc00 handler has already clobbered CTR
+ * and CR0, so PR-KVM can not support a guest kernel that preserves
+ * those registers across its system calls.
+ *
+ * The state of registers is as kvmppc_interrupt, 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
-        *
-        * This may also be a syscall from PR-KVM userspace that is to be
-        * reflected to the PR guest kernel, so registers may be set up for
-        * a system call rather than hcall. We don't currently clobber
-        * anything here, but the 0xc00 handler has already clobbered CTR
-        * and CR0, so PR-KVM can not support a guest kernel that preserves
-        * those registers across its system calls.
-        */
-        /*
-         * 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 */
+       li      r11,PACA_EXGEN
+       b       .Lgot_save_area
 
 /*
  * KVM interrupt entry occurs after GEN_INT_ENTRY runs, and follows that
@@ -67,12 +57,12 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
 kvmppc_interrupt:
        li      r11,PACA_EXGEN
        cmpdi   r10,0x200
-       bgt+    1f
+       bgt+    .Lgot_save_area
        li      r11,PACA_EXMC
-       beq     1f
+       beq     .Lgot_save_area
        li      r11,PACA_EXNMI
-1:     add     r11,r11,r13
-
+.Lgot_save_area:
+       add     r11,r11,r13
 BEGIN_FTR_SECTION
        ld      r12,EX_CFAR(r11)
        std     r12,HSTATE_CFAR(r13)
@@ -91,7 +81,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: