KVM: PPC: Book3S: Change interrupt call to reduce scratch space use on HV
authorNicholas Piggin <npiggin@gmail.com>
Wed, 21 Dec 2016 18:29:25 +0000 (04:29 +1000)
committerMichael Ellerman <mpe@ellerman.id.au>
Fri, 27 Jan 2017 04:41:20 +0000 (15:41 +1100)
Change the calling convention to put the trap number together with
CR in two halves of r12, which frees up HSTATE_SCRATCH2 in the HV
handler.

The 64-bit PR handler entry translates the calling convention back
to match the previous call convention (i.e., shared with 32-bit), for
simplicity.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Acked-by: Paul Mackerras <paulus@ozlabs.org>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
arch/powerpc/include/asm/exception-64s.h
arch/powerpc/kvm/book3s_hv_rmhandlers.S
arch/powerpc/kvm/book3s_segment.S

index 9a3eee66129766d84d8bd5063fd8ecd142e8fc21..a02a268bde6bf0f9a271567f430c70b56cfb4cca 100644 (file)
@@ -233,7 +233,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
 
 #endif
 
-#define __KVM_HANDLER_PROLOG(area, n)                                  \
+#define __KVM_HANDLER(area, h, n)                                      \
        BEGIN_FTR_SECTION_NESTED(947)                                   \
        ld      r10,area+EX_CFAR(r13);                                  \
        std     r10,HSTATE_CFAR(r13);                                   \
@@ -243,30 +243,28 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
        std     r10,HSTATE_PPR(r13);                                    \
        END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,948);    \
        ld      r10,area+EX_R10(r13);                                   \
-       stw     r9,HSTATE_SCRATCH1(r13);                                \
-       ld      r9,area+EX_R9(r13);                                     \
        std     r12,HSTATE_SCRATCH0(r13);                               \
-
-#define __KVM_HANDLER(area, h, n)                                      \
-       __KVM_HANDLER_PROLOG(area, n)                                   \
-       li      r12,n;                                                  \
+       sldi    r12,r9,32;                                              \
+       ori     r12,r12,(n);                                            \
+       ld      r9,area+EX_R9(r13);                                     \
        b       kvmppc_interrupt
 
 #define __KVM_HANDLER_SKIP(area, h, n)                                 \
        cmpwi   r10,KVM_GUEST_MODE_SKIP;                                \
-       ld      r10,area+EX_R10(r13);                                   \
        beq     89f;                                                    \
-       stw     r9,HSTATE_SCRATCH1(r13);                                \
        BEGIN_FTR_SECTION_NESTED(948)                                   \
-       ld      r9,area+EX_PPR(r13);                                    \
-       std     r9,HSTATE_PPR(r13);                                     \
+       ld      r10,area+EX_PPR(r13);                                   \
+       std     r10,HSTATE_PPR(r13);                                    \
        END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,948);    \
-       ld      r9,area+EX_R9(r13);                                     \
+       ld      r10,area+EX_R10(r13);                                   \
        std     r12,HSTATE_SCRATCH0(r13);                               \
-       li      r12,n;                                                  \
+       sldi    r12,r9,32;                                              \
+       ori     r12,r12,(n);                                            \
+       ld      r9,area+EX_R9(r13);                                     \
        b       kvmppc_interrupt;                                       \
 89:    mtocrf  0x80,r9;                                                \
        ld      r9,area+EX_R9(r13);                                     \
+       ld      r10,area+EX_R10(r13);                                   \
        b       kvmppc_skip_##h##interrupt
 
 #ifdef CONFIG_KVM_BOOK3S_64_HANDLER
index 9338a818e05cf8a7285471bca75cad2c8c2a7a46..11882aac8216f8e3f860fb10f3f0fd97f2d40b80 100644 (file)
@@ -1057,19 +1057,18 @@ hdec_soon:
 kvmppc_interrupt_hv:
        /*
         * Register contents:
-        * R12          = interrupt vector
+        * R12          = (guest CR << 32) | interrupt vector
         * R13          = PACA
-        * guest CR, R12 saved in shadow VCPU SCRATCH1/0
+        * guest R12 saved in shadow VCPU SCRATCH0
         * guest R13 saved in SPRN_SCRATCH0
         */
-       std     r9, HSTATE_SCRATCH2(r13)
-
+       std     r9, HSTATE_SCRATCH1(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)
+       ld      r9, HSTATE_SCRATCH1(r13)
        beq     kvmppc_interrupt_pr
 #endif
        /* We're now back in the host but in guest MMU context */
@@ -1089,13 +1088,14 @@ kvmppc_interrupt_hv:
        std     r6, VCPU_GPR(R6)(r9)
        std     r7, VCPU_GPR(R7)(r9)
        std     r8, VCPU_GPR(R8)(r9)
-       ld      r0, HSTATE_SCRATCH2(r13)
+       ld      r0, HSTATE_SCRATCH1(r13)
        std     r0, VCPU_GPR(R9)(r9)
        std     r10, VCPU_GPR(R10)(r9)
        std     r11, VCPU_GPR(R11)(r9)
        ld      r3, HSTATE_SCRATCH0(r13)
-       lwz     r4, HSTATE_SCRATCH1(r13)
        std     r3, VCPU_GPR(R12)(r9)
+       /* CR is in the high half of r12 */
+       srdi    r4, r12, 32
        stw     r4, VCPU_CR(r9)
 BEGIN_FTR_SECTION
        ld      r3, HSTATE_CFAR(r13)
@@ -1114,6 +1114,8 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
        mfspr   r11, SPRN_SRR1
        std     r10, VCPU_SRR0(r9)
        std     r11, VCPU_SRR1(r9)
+       /* trap is in the low half of r12, clear CR from the high half */
+       clrldi  r12, r12, 32
        andi.   r0, r12, 2              /* need to read HSRR0/1? */
        beq     1f
        mfspr   r10, SPRN_HSRR0
index ca8f174289bb43a148bdd9159f71ca645e0c416a..68e45080cf93d544d56f81161ddd80e519e05813 100644 (file)
@@ -167,20 +167,31 @@ kvmppc_handler_trampoline_enter_end:
  *                                                                            *
  *****************************************************************************/
 
-.global kvmppc_handler_trampoline_exit
-kvmppc_handler_trampoline_exit:
-
 .global kvmppc_interrupt_pr
 kvmppc_interrupt_pr:
+       /* 64-bit entry. Register usage at this point:
+        *
+        * SPRG_SCRATCH0   = guest R13
+        * R12             = (guest CR << 32) | exit handler id
+        * R13             = PACA
+        * HSTATE.SCRATCH0 = guest R12
+        */
+#ifdef CONFIG_PPC64
+       /* Match 32-bit entry */
+       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 */
+#endif
 
+.global kvmppc_handler_trampoline_exit
+kvmppc_handler_trampoline_exit:
        /* Register usage at this point:
         *
-        * SPRG_SCRATCH0  = guest R13
-        * R12            = exit handler id
-        * R13            = shadow vcpu (32-bit) or PACA (64-bit)
+        * SPRG_SCRATCH0   = guest R13
+        * R12             = exit handler id
+        * R13             = shadow vcpu (32-bit) or PACA (64-bit)
         * HSTATE.SCRATCH0 = guest R12
         * HSTATE.SCRATCH1 = guest CR
-        *
         */
 
        /* Save registers */