KVM: PPC: Book3S HV: Support POWER6 compatibility mode on POWER7
[firefly-linux-kernel-4.4.55.git] / arch / powerpc / kvm / book3s_hv_rmhandlers.S
index 0effcd1442411db6de3e94b14699bbc9d77bcd5a..cd39632a646edd2cbddb3aa06c328d1d81f8dac9 100644 (file)
@@ -499,7 +499,13 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201)
        addis   r8,r8,0x100     /* if so, increment upper 40 bits */
        mtspr   SPRN_TBU40,r8
 
-37:    li      r0,1
+       /* Load guest PCR value to select appropriate compat mode */
+37:    ld      r7, VCORE_PCR(r5)
+       cmpdi   r7, 0
+       beq     38f
+       mtspr   SPRN_PCR, r7
+38:
+       li      r0,1
        stb     r0,VCORE_IN_GUEST(r5)   /* signal secondaries to continue */
        b       10f
 
@@ -509,7 +515,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201)
        beq     20b
 
        /* Set LPCR and RMOR. */
-10:    ld      r8,KVM_LPCR(r9)
+10:    ld      r8,VCORE_LPCR(r5)
        mtspr   SPRN_LPCR,r8
        ld      r8,KVM_RMOR(r9)
        mtspr   SPRN_RMOR,r8
@@ -571,7 +577,8 @@ toc_tlbie_lock:
        bne     24b
        isync
 
-       ld      r7,KVM_LPCR(r9)         /* use kvm->arch.lpcr to store HID4 */
+       ld      r5,HSTATE_KVM_VCORE(r13)
+       ld      r7,VCORE_LPCR(r5)       /* use vcore->lpcr to store HID4 */
        li      r0,0x18f
        rotldi  r0,r0,HID4_LPID5_SH     /* all lpid bits in HID4 = 1 */
        or      r0,r7,r0
@@ -716,13 +723,15 @@ BEGIN_FTR_SECTION
        ld      r5, VCPU_CFAR(r4)
        mtspr   SPRN_CFAR, r5
 END_FTR_SECTION_IFSET(CPU_FTR_CFAR)
+BEGIN_FTR_SECTION
+       ld      r0, VCPU_PPR(r4)
+END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
 
        ld      r5, VCPU_LR(r4)
        lwz     r6, VCPU_CR(r4)
        mtlr    r5
        mtcr    r6
 
-       ld      r0, VCPU_GPR(R0)(r4)
        ld      r1, VCPU_GPR(R1)(r4)
        ld      r2, VCPU_GPR(R2)(r4)
        ld      r3, VCPU_GPR(R3)(r4)
@@ -736,6 +745,10 @@ END_FTR_SECTION_IFSET(CPU_FTR_CFAR)
        ld      r12, VCPU_GPR(R12)(r4)
        ld      r13, VCPU_GPR(R13)(r4)
 
+BEGIN_FTR_SECTION
+       mtspr   SPRN_PPR, r0
+END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
+       ld      r0, VCPU_GPR(R0)(r4)
        ld      r4, VCPU_GPR(R4)(r4)
 
        hrfid
@@ -786,6 +799,10 @@ BEGIN_FTR_SECTION
        ld      r3, HSTATE_CFAR(r13)
        std     r3, VCPU_CFAR(r9)
 END_FTR_SECTION_IFSET(CPU_FTR_CFAR)
+BEGIN_FTR_SECTION
+       ld      r4, HSTATE_PPR(r13)
+       std     r4, VCPU_PPR(r9)
+END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
 
        /* Restore R1/R2 so we can handle faults */
        ld      r1, HSTATE_HOST_R1(r13)
@@ -1083,8 +1100,14 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201)
        addis   r8,r8,0x100             /* if so, increment upper 40 bits */
        mtspr   SPRN_TBU40,r8
 
+       /* Reset PCR */
+17:    ld      r0, VCORE_PCR(r5)
+       cmpdi   r0, 0
+       beq     18f
+       li      r0, 0
+       mtspr   SPRN_PCR, r0
+18:
        /* Signal secondary CPUs to continue */
-17:    li      r0,0
        stb     r0,VCORE_IN_GUEST(r5)
        lis     r8,0x7fff               /* MAX_INT@h */
        mtspr   SPRN_HDEC,r8