KVM: PPC: Book3S HV: Add new state for transactional memory
authorMichael Neuling <mikey@neuling.org>
Wed, 8 Jan 2014 10:25:32 +0000 (21:25 +1100)
committerAlexander Graf <agraf@suse.de>
Mon, 27 Jan 2014 15:01:20 +0000 (16:01 +0100)
Add new state for transactional memory (TM) to kvm_vcpu_arch.  Also add
asm-offset bits that are going to be required.

This also moves the existing TFHAR, TFIAR and TEXASR SPRs into a
CONFIG_PPC_TRANSACTIONAL_MEM section.  This requires some code changes to
ensure we still compile with CONFIG_PPC_TRANSACTIONAL_MEM=N.  Much of the added
the added #ifdefs are removed in a later patch when the bulk of the TM code is
added.

Signed-off-by: Michael Neuling <mikey@neuling.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
[agraf: fix merge conflict]
Signed-off-by: Alexander Graf <agraf@suse.de>
arch/powerpc/include/asm/kvm_host.h
arch/powerpc/kernel/asm-offsets.c
arch/powerpc/kvm/book3s_hv.c
arch/powerpc/kvm/book3s_hv_rmhandlers.S

index 7726a3bc8ff07b2a6194e80318601d11381179ec..1eaea2dea1745e6310eb3918f2a99c0e2d8bd767 100644 (file)
@@ -475,9 +475,6 @@ struct kvm_vcpu_arch {
        ulong ppr;
        ulong pspb;
        ulong fscr;
-       ulong tfhar;
-       ulong tfiar;
-       ulong texasr;
        ulong ebbhr;
        ulong ebbrr;
        ulong bescr;
@@ -526,6 +523,27 @@ struct kvm_vcpu_arch {
        u64 siar;
        u64 sdar;
        u64 sier;
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+       u64 tfhar;
+       u64 texasr;
+       u64 tfiar;
+
+       u32 cr_tm;
+       u64 lr_tm;
+       u64 ctr_tm;
+       u64 amr_tm;
+       u64 ppr_tm;
+       u64 dscr_tm;
+       u64 tar_tm;
+
+       ulong gpr_tm[32];
+
+       struct thread_fp_state fp_tm;
+
+       struct thread_vr_state vr_tm;
+       u32 vrsave_tm; /* also USPRG0 */
+
+#endif
 
 #ifdef CONFIG_KVM_EXIT_TIMING
        struct mutex exit_timing_lock;
index a60a2fdae5bd08d502096ec88e006bc8f7d964c2..687f2ebf0ccee0b36675a57abeb995aef7247bd3 100644 (file)
@@ -521,9 +521,6 @@ int main(void)
        DEFINE(VCPU_PPR, offsetof(struct kvm_vcpu, arch.ppr));
        DEFINE(VCPU_FSCR, offsetof(struct kvm_vcpu, arch.fscr));
        DEFINE(VCPU_PSPB, offsetof(struct kvm_vcpu, arch.pspb));
-       DEFINE(VCPU_TFHAR, offsetof(struct kvm_vcpu, arch.tfhar));
-       DEFINE(VCPU_TFIAR, offsetof(struct kvm_vcpu, arch.tfiar));
-       DEFINE(VCPU_TEXASR, offsetof(struct kvm_vcpu, arch.texasr));
        DEFINE(VCPU_EBBHR, offsetof(struct kvm_vcpu, arch.ebbhr));
        DEFINE(VCPU_EBBRR, offsetof(struct kvm_vcpu, arch.ebbrr));
        DEFINE(VCPU_BESCR, offsetof(struct kvm_vcpu, arch.bescr));
@@ -545,6 +542,22 @@ int main(void)
        DEFINE(VCPU_SLB_E, offsetof(struct kvmppc_slb, orige));
        DEFINE(VCPU_SLB_V, offsetof(struct kvmppc_slb, origv));
        DEFINE(VCPU_SLB_SIZE, sizeof(struct kvmppc_slb));
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+       DEFINE(VCPU_TFHAR, offsetof(struct kvm_vcpu, arch.tfhar));
+       DEFINE(VCPU_TFIAR, offsetof(struct kvm_vcpu, arch.tfiar));
+       DEFINE(VCPU_TEXASR, offsetof(struct kvm_vcpu, arch.texasr));
+       DEFINE(VCPU_GPR_TM, offsetof(struct kvm_vcpu, arch.gpr_tm));
+       DEFINE(VCPU_FPRS_TM, offsetof(struct kvm_vcpu, arch.fp_tm.fpr));
+       DEFINE(VCPU_VRS_TM, offsetof(struct kvm_vcpu, arch.vr_tm.vr));
+       DEFINE(VCPU_VRSAVE_TM, offsetof(struct kvm_vcpu, arch.vrsave_tm));
+       DEFINE(VCPU_CR_TM, offsetof(struct kvm_vcpu, arch.cr_tm));
+       DEFINE(VCPU_LR_TM, offsetof(struct kvm_vcpu, arch.lr_tm));
+       DEFINE(VCPU_CTR_TM, offsetof(struct kvm_vcpu, arch.ctr_tm));
+       DEFINE(VCPU_AMR_TM, offsetof(struct kvm_vcpu, arch.amr_tm));
+       DEFINE(VCPU_PPR_TM, offsetof(struct kvm_vcpu, arch.ppr_tm));
+       DEFINE(VCPU_DSCR_TM, offsetof(struct kvm_vcpu, arch.dscr_tm));
+       DEFINE(VCPU_TAR_TM, offsetof(struct kvm_vcpu, arch.tar_tm));
+#endif
 
 #ifdef CONFIG_PPC_BOOK3S_64
 #ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE
index 3195e4f8a2ed019642fe27e36e3f2745c7024644..f4a4c5c82fb250d7af8fac85de4cf2acaf47768c 100644 (file)
@@ -875,6 +875,7 @@ static int kvmppc_get_one_reg_hv(struct kvm_vcpu *vcpu, u64 id,
        case KVM_REG_PPC_IAMR:
                *val = get_reg_val(id, vcpu->arch.iamr);
                break;
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
        case KVM_REG_PPC_TFHAR:
                *val = get_reg_val(id, vcpu->arch.tfhar);
                break;
@@ -884,6 +885,7 @@ static int kvmppc_get_one_reg_hv(struct kvm_vcpu *vcpu, u64 id,
        case KVM_REG_PPC_TEXASR:
                *val = get_reg_val(id, vcpu->arch.texasr);
                break;
+#endif
        case KVM_REG_PPC_FSCR:
                *val = get_reg_val(id, vcpu->arch.fscr);
                break;
@@ -1033,6 +1035,7 @@ static int kvmppc_set_one_reg_hv(struct kvm_vcpu *vcpu, u64 id,
        case KVM_REG_PPC_IAMR:
                vcpu->arch.iamr = set_reg_val(id, *val);
                break;
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
        case KVM_REG_PPC_TFHAR:
                vcpu->arch.tfhar = set_reg_val(id, *val);
                break;
@@ -1042,6 +1045,7 @@ static int kvmppc_set_one_reg_hv(struct kvm_vcpu *vcpu, u64 id,
        case KVM_REG_PPC_TEXASR:
                vcpu->arch.texasr = set_reg_val(id, *val);
                break;
+#endif
        case KVM_REG_PPC_FSCR:
                vcpu->arch.fscr = set_reg_val(id, *val);
                break;
index ecb76357c9d0aa5b60e6d0663eeadd3d82479f7d..dfa144cb199bb408d7df7b10d481383f924b3a44 100644 (file)
@@ -701,13 +701,15 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S)
        ld      r6, VCPU_VTB(r4)
        mtspr   SPRN_IC, r5
        mtspr   SPRN_VTB, r6
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
        ld      r5, VCPU_TFHAR(r4)
        ld      r6, VCPU_TFIAR(r4)
        ld      r7, VCPU_TEXASR(r4)
-       ld      r8, VCPU_EBBHR(r4)
        mtspr   SPRN_TFHAR, r5
        mtspr   SPRN_TFIAR, r6
        mtspr   SPRN_TEXASR, r7
+#endif
+       ld      r8, VCPU_EBBHR(r4)
        mtspr   SPRN_EBBHR, r8
        ld      r5, VCPU_EBBRR(r4)
        ld      r6, VCPU_BESCR(r4)
@@ -1118,13 +1120,15 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S)
        std     r5, VCPU_IC(r9)
        std     r6, VCPU_VTB(r9)
        std     r7, VCPU_TAR(r9)
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
        mfspr   r5, SPRN_TFHAR
        mfspr   r6, SPRN_TFIAR
        mfspr   r7, SPRN_TEXASR
-       mfspr   r8, SPRN_EBBHR
        std     r5, VCPU_TFHAR(r9)
        std     r6, VCPU_TFIAR(r9)
        std     r7, VCPU_TEXASR(r9)
+#endif
+       mfspr   r8, SPRN_EBBHR
        std     r8, VCPU_EBBHR(r9)
        mfspr   r5, SPRN_EBBRR
        mfspr   r6, SPRN_BESCR
@@ -1497,6 +1501,73 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
 1:     addi    r8,r8,16
        .endr
 
+       /* Save DEC */
+       mfspr   r5,SPRN_DEC
+       mftb    r6
+       extsw   r5,r5
+       add     r5,r5,r6
+       std     r5,VCPU_DEC_EXPIRES(r9)
+
+BEGIN_FTR_SECTION
+       b       8f
+END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S)
+       /* Turn on TM so we can access TFHAR/TFIAR/TEXASR */
+       mfmsr   r8
+       li      r0, 1
+       rldimi  r8, r0, MSR_TM_LG, 63-MSR_TM_LG
+       mtmsrd  r8
+
+       /* Save POWER8-specific registers */
+       mfspr   r5, SPRN_IAMR
+       mfspr   r6, SPRN_PSPB
+       mfspr   r7, SPRN_FSCR
+       std     r5, VCPU_IAMR(r9)
+       stw     r6, VCPU_PSPB(r9)
+       std     r7, VCPU_FSCR(r9)
+       mfspr   r5, SPRN_IC
+       mfspr   r6, SPRN_VTB
+       mfspr   r7, SPRN_TAR
+       std     r5, VCPU_IC(r9)
+       std     r6, VCPU_VTB(r9)
+       std     r7, VCPU_TAR(r9)
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+       mfspr   r5, SPRN_TFHAR
+       mfspr   r6, SPRN_TFIAR
+       mfspr   r7, SPRN_TEXASR
+       std     r5, VCPU_TFHAR(r9)
+       std     r6, VCPU_TFIAR(r9)
+       std     r7, VCPU_TEXASR(r9)
+#endif
+       mfspr   r8, SPRN_EBBHR
+       std     r8, VCPU_EBBHR(r9)
+       mfspr   r5, SPRN_EBBRR
+       mfspr   r6, SPRN_BESCR
+       mfspr   r7, SPRN_CSIGR
+       mfspr   r8, SPRN_TACR
+       std     r5, VCPU_EBBRR(r9)
+       std     r6, VCPU_BESCR(r9)
+       std     r7, VCPU_CSIGR(r9)
+       std     r8, VCPU_TACR(r9)
+       mfspr   r5, SPRN_TCSCR
+       mfspr   r6, SPRN_ACOP
+       mfspr   r7, SPRN_PID
+       mfspr   r8, SPRN_WORT
+       std     r5, VCPU_TCSCR(r9)
+       std     r6, VCPU_ACOP(r9)
+       stw     r7, VCPU_GUEST_PID(r9)
+       std     r8, VCPU_WORT(r9)
+8:
+
+       /* Save and reset AMR and UAMOR before turning on the MMU */
+BEGIN_FTR_SECTION
+       mfspr   r5,SPRN_AMR
+       mfspr   r6,SPRN_UAMOR
+       std     r5,VCPU_AMR(r9)
+       std     r6,VCPU_UAMOR(r9)
+       li      r6,0
+       mtspr   SPRN_AMR,r6
+END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206)
+
        /* Unset guest mode */
        li      r0, KVM_GUEST_MODE_NONE
        stb     r0, HSTATE_IN_GUEST(r13)