diff options
Diffstat (limited to 'arch/powerpc/kvm/book3s_segment.S')
-rw-r--r-- | arch/powerpc/kvm/book3s_segment.S | 117 |
1 files changed, 64 insertions, 53 deletions
diff --git a/arch/powerpc/kvm/book3s_segment.S b/arch/powerpc/kvm/book3s_segment.S index 451264274b8c..aed32e517212 100644 --- a/arch/powerpc/kvm/book3s_segment.S +++ b/arch/powerpc/kvm/book3s_segment.S @@ -22,7 +22,7 @@ #if defined(CONFIG_PPC_BOOK3S_64) #define GET_SHADOW_VCPU(reg) \ - addi reg, r13, PACA_KVM_SVCPU + mr reg, r13 #elif defined(CONFIG_PPC_BOOK3S_32) @@ -71,6 +71,10 @@ kvmppc_handler_trampoline_enter: /* r3 = shadow vcpu */ GET_SHADOW_VCPU(r3) + /* Save R1/R2 in the PACA (64-bit) or shadow_vcpu (32-bit) */ + PPC_STL r1, HSTATE_HOST_R1(r3) + PPC_STL r2, HSTATE_HOST_R2(r3) + /* Move SRR0 and SRR1 into the respective regs */ PPC_LL r9, SVCPU_PC(r3) mtsrr0 r9 @@ -78,36 +82,36 @@ kvmppc_handler_trampoline_enter: /* Activate guest mode, so faults get handled by KVM */ li r11, KVM_GUEST_MODE_GUEST - stb r11, SVCPU_IN_GUEST(r3) + stb r11, HSTATE_IN_GUEST(r3) /* Switch to guest segment. This is subarch specific. */ LOAD_GUEST_SEGMENTS /* Enter guest */ - PPC_LL r4, (SVCPU_CTR)(r3) - PPC_LL r5, (SVCPU_LR)(r3) - lwz r6, (SVCPU_CR)(r3) - lwz r7, (SVCPU_XER)(r3) + PPC_LL r4, SVCPU_CTR(r3) + PPC_LL r5, SVCPU_LR(r3) + lwz r6, SVCPU_CR(r3) + lwz r7, SVCPU_XER(r3) mtctr r4 mtlr r5 mtcr r6 mtxer r7 - PPC_LL r0, (SVCPU_R0)(r3) - PPC_LL r1, (SVCPU_R1)(r3) - PPC_LL r2, (SVCPU_R2)(r3) - PPC_LL r4, (SVCPU_R4)(r3) - PPC_LL r5, (SVCPU_R5)(r3) - PPC_LL r6, (SVCPU_R6)(r3) - PPC_LL r7, (SVCPU_R7)(r3) - PPC_LL r8, (SVCPU_R8)(r3) - PPC_LL r9, (SVCPU_R9)(r3) - PPC_LL r10, (SVCPU_R10)(r3) - PPC_LL r11, (SVCPU_R11)(r3) - PPC_LL r12, (SVCPU_R12)(r3) - PPC_LL r13, (SVCPU_R13)(r3) + PPC_LL r0, SVCPU_R0(r3) + PPC_LL r1, SVCPU_R1(r3) + PPC_LL r2, SVCPU_R2(r3) + PPC_LL r4, SVCPU_R4(r3) + PPC_LL r5, SVCPU_R5(r3) + PPC_LL r6, SVCPU_R6(r3) + PPC_LL r7, SVCPU_R7(r3) + PPC_LL r8, SVCPU_R8(r3) + PPC_LL r9, SVCPU_R9(r3) + PPC_LL r10, SVCPU_R10(r3) + PPC_LL r11, SVCPU_R11(r3) + PPC_LL r12, SVCPU_R12(r3) + PPC_LL r13, SVCPU_R13(r3) PPC_LL r3, (SVCPU_R3)(r3) @@ -125,56 +129,63 @@ kvmppc_handler_trampoline_enter_end: .global kvmppc_handler_trampoline_exit kvmppc_handler_trampoline_exit: +.global kvmppc_interrupt +kvmppc_interrupt: + /* Register usage at this point: * * SPRG_SCRATCH0 = guest R13 * R12 = exit handler id - * R13 = shadow vcpu - SHADOW_VCPU_OFF [=PACA on PPC64] - * SVCPU.SCRATCH0 = guest R12 - * SVCPU.SCRATCH1 = guest CR + * R13 = shadow vcpu (32-bit) or PACA (64-bit) + * HSTATE.SCRATCH0 = guest R12 + * HSTATE.SCRATCH1 = guest CR * */ /* Save registers */ - PPC_STL r0, (SHADOW_VCPU_OFF + SVCPU_R0)(r13) - PPC_STL r1, (SHADOW_VCPU_OFF + SVCPU_R1)(r13) - PPC_STL r2, (SHADOW_VCPU_OFF + SVCPU_R2)(r13) - PPC_STL r3, (SHADOW_VCPU_OFF + SVCPU_R3)(r13) - PPC_STL r4, (SHADOW_VCPU_OFF + SVCPU_R4)(r13) - PPC_STL r5, (SHADOW_VCPU_OFF + SVCPU_R5)(r13) - PPC_STL r6, (SHADOW_VCPU_OFF + SVCPU_R6)(r13) - PPC_STL r7, (SHADOW_VCPU_OFF + SVCPU_R7)(r13) - PPC_STL r8, (SHADOW_VCPU_OFF + SVCPU_R8)(r13) - PPC_STL r9, (SHADOW_VCPU_OFF + SVCPU_R9)(r13) - PPC_STL r10, (SHADOW_VCPU_OFF + SVCPU_R10)(r13) - PPC_STL r11, (SHADOW_VCPU_OFF + SVCPU_R11)(r13) + PPC_STL r0, SVCPU_R0(r13) + PPC_STL r1, SVCPU_R1(r13) + PPC_STL r2, SVCPU_R2(r13) + PPC_STL r3, SVCPU_R3(r13) + PPC_STL r4, SVCPU_R4(r13) + PPC_STL r5, SVCPU_R5(r13) + PPC_STL r6, SVCPU_R6(r13) + PPC_STL r7, SVCPU_R7(r13) + PPC_STL r8, SVCPU_R8(r13) + PPC_STL r9, SVCPU_R9(r13) + PPC_STL r10, SVCPU_R10(r13) + PPC_STL r11, SVCPU_R11(r13) /* Restore R1/R2 so we can handle faults */ - PPC_LL r1, (SHADOW_VCPU_OFF + SVCPU_HOST_R1)(r13) - PPC_LL r2, (SHADOW_VCPU_OFF + SVCPU_HOST_R2)(r13) + PPC_LL r1, HSTATE_HOST_R1(r13) + PPC_LL r2, HSTATE_HOST_R2(r13) /* Save guest PC and MSR */ +#ifdef CONFIG_PPC64 +BEGIN_FTR_SECTION andi. r0,r12,0x2 beq 1f mfspr r3,SPRN_HSRR0 mfspr r4,SPRN_HSRR1 andi. r12,r12,0x3ffd b 2f +END_FTR_SECTION_IFSET(CPU_FTR_HVMODE) +#endif 1: mfsrr0 r3 mfsrr1 r4 2: - PPC_STL r3, (SHADOW_VCPU_OFF + SVCPU_PC)(r13) - PPC_STL r4, (SHADOW_VCPU_OFF + SVCPU_SHADOW_SRR1)(r13) + PPC_STL r3, SVCPU_PC(r13) + PPC_STL r4, SVCPU_SHADOW_SRR1(r13) /* Get scratch'ed off registers */ GET_SCRATCH0(r9) - PPC_LL r8, (SHADOW_VCPU_OFF + SVCPU_SCRATCH0)(r13) - lwz r7, (SHADOW_VCPU_OFF + SVCPU_SCRATCH1)(r13) + PPC_LL r8, HSTATE_SCRATCH0(r13) + lwz r7, HSTATE_SCRATCH1(r13) - PPC_STL r9, (SHADOW_VCPU_OFF + SVCPU_R13)(r13) - PPC_STL r8, (SHADOW_VCPU_OFF + SVCPU_R12)(r13) - stw r7, (SHADOW_VCPU_OFF + SVCPU_CR)(r13) + PPC_STL r9, SVCPU_R13(r13) + PPC_STL r8, SVCPU_R12(r13) + stw r7, SVCPU_CR(r13) /* Save more register state */ @@ -184,11 +195,11 @@ kvmppc_handler_trampoline_exit: mfctr r8 mflr r9 - stw r5, (SHADOW_VCPU_OFF + SVCPU_XER)(r13) - PPC_STL r6, (SHADOW_VCPU_OFF + SVCPU_FAULT_DAR)(r13) - stw r7, (SHADOW_VCPU_OFF + SVCPU_FAULT_DSISR)(r13) - PPC_STL r8, (SHADOW_VCPU_OFF + SVCPU_CTR)(r13) - PPC_STL r9, (SHADOW_VCPU_OFF + SVCPU_LR)(r13) + stw r5, SVCPU_XER(r13) + PPC_STL r6, SVCPU_FAULT_DAR(r13) + stw r7, SVCPU_FAULT_DSISR(r13) + PPC_STL r8, SVCPU_CTR(r13) + PPC_STL r9, SVCPU_LR(r13) /* * In order for us to easily get the last instruction, @@ -218,7 +229,7 @@ ld_last_inst: /* Set guest mode to 'jump over instruction' so if lwz faults * we'll just continue at the next IP. */ li r9, KVM_GUEST_MODE_SKIP - stb r9, (SHADOW_VCPU_OFF + SVCPU_IN_GUEST)(r13) + stb r9, HSTATE_IN_GUEST(r13) /* 1) enable paging for data */ mfmsr r9 @@ -232,13 +243,13 @@ ld_last_inst: sync #endif - stw r0, (SHADOW_VCPU_OFF + SVCPU_LAST_INST)(r13) + stw r0, SVCPU_LAST_INST(r13) no_ld_last_inst: /* Unset guest mode */ li r9, KVM_GUEST_MODE_NONE - stb r9, (SHADOW_VCPU_OFF + SVCPU_IN_GUEST)(r13) + stb r9, HSTATE_IN_GUEST(r13) /* Switch back to host MMU */ LOAD_HOST_SEGMENTS @@ -248,7 +259,7 @@ no_ld_last_inst: * R1 = host R1 * R2 = host R2 * R12 = exit handler id - * R13 = shadow vcpu - SHADOW_VCPU_OFF [=PACA on PPC64] + * R13 = shadow vcpu (32-bit) or PACA (64-bit) * SVCPU.* = guest * * */ @@ -258,7 +269,7 @@ no_ld_last_inst: ori r7, r7, MSR_IR|MSR_DR|MSR_RI|MSR_ME /* Enable paging */ mtsrr1 r7 /* Load highmem handler address */ - PPC_LL r8, (SHADOW_VCPU_OFF + SVCPU_VMHANDLER)(r13) + PPC_LL r8, HSTATE_VMHANDLER(r13) mtsrr0 r8 RFI |