diff -ur linux-4.4.0.orig/arch/powerpc/include/asm/kvm_book3s.h linux-4.4.0/arch/powerpc/include/asm/kvm_book3s.h --- linux-4.4.0.orig/arch/powerpc/include/asm/kvm_book3s.h 2016-01-11 10:01:32.000000000 +1100 +++ linux-4.4.0/arch/powerpc/include/asm/kvm_book3s.h 2017-10-24 16:36:02.906876971 +1100 @@ -83,6 +83,7 @@ u64 sdr1; u64 hior; u64 msr_mask; + u64 vtb; #ifdef CONFIG_PPC_BOOK3S_32 u32 vsid_pool[VSID_POOL_SIZE]; u32 vsid_next; diff -ur linux-4.4.0.orig/arch/powerpc/include/asm/kvm_host.h linux-4.4.0/arch/powerpc/include/asm/kvm_host.h --- linux-4.4.0.orig/arch/powerpc/include/asm/kvm_host.h 2017-10-24 16:34:51.000000000 +1100 +++ linux-4.4.0/arch/powerpc/include/asm/kvm_host.h 2017-10-24 16:36:57.516144321 +1100 @@ -297,6 +297,7 @@ u32 arch_compat; ulong pcr; ulong dpdes; /* doorbell state (POWER8) */ + ulong vtb; /* virtual timebase */ ulong conferring_threads; }; @@ -473,7 +474,6 @@ ulong purr; ulong spurr; ulong ic; - ulong vtb; ulong dscr; ulong amr; ulong uamor; diff -ur linux-4.4.0.orig/arch/powerpc/kernel/asm-offsets.c linux-4.4.0/arch/powerpc/kernel/asm-offsets.c --- linux-4.4.0.orig/arch/powerpc/kernel/asm-offsets.c 2017-10-24 16:34:51.000000000 +1100 +++ linux-4.4.0/arch/powerpc/kernel/asm-offsets.c 2017-10-24 16:36:02.906876971 +1100 @@ -519,7 +519,6 @@ DEFINE(VCPU_PURR, offsetof(struct kvm_vcpu, arch.purr)); DEFINE(VCPU_SPURR, offsetof(struct kvm_vcpu, arch.spurr)); DEFINE(VCPU_IC, offsetof(struct kvm_vcpu, arch.ic)); - DEFINE(VCPU_VTB, offsetof(struct kvm_vcpu, arch.vtb)); DEFINE(VCPU_DSCR, offsetof(struct kvm_vcpu, arch.dscr)); DEFINE(VCPU_AMR, offsetof(struct kvm_vcpu, arch.amr)); DEFINE(VCPU_UAMOR, offsetof(struct kvm_vcpu, arch.uamor)); @@ -572,6 +571,7 @@ DEFINE(VCORE_LPCR, offsetof(struct kvmppc_vcore, lpcr)); DEFINE(VCORE_PCR, offsetof(struct kvmppc_vcore, pcr)); DEFINE(VCORE_DPDES, offsetof(struct kvmppc_vcore, dpdes)); + DEFINE(VCORE_VTB, offsetof(struct kvmppc_vcore, vtb)); 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)); diff -ur linux-4.4.0.orig/arch/powerpc/kvm/book3s.c linux-4.4.0/arch/powerpc/kvm/book3s.c --- linux-4.4.0.orig/arch/powerpc/kvm/book3s.c 2016-01-11 10:01:32.000000000 +1100 +++ linux-4.4.0/arch/powerpc/kvm/book3s.c 2017-10-24 16:36:02.906876971 +1100 @@ -591,9 +591,6 @@ case KVM_REG_PPC_BESCR: *val = get_reg_val(id, vcpu->arch.bescr); break; - case KVM_REG_PPC_VTB: - *val = get_reg_val(id, vcpu->arch.vtb); - break; case KVM_REG_PPC_IC: *val = get_reg_val(id, vcpu->arch.ic); break; @@ -665,9 +662,6 @@ case KVM_REG_PPC_BESCR: vcpu->arch.bescr = set_reg_val(id, *val); break; - case KVM_REG_PPC_VTB: - vcpu->arch.vtb = set_reg_val(id, *val); - break; case KVM_REG_PPC_IC: vcpu->arch.ic = set_reg_val(id, *val); break; diff -ur linux-4.4.0.orig/arch/powerpc/kvm/book3s_emulate.c linux-4.4.0/arch/powerpc/kvm/book3s_emulate.c --- linux-4.4.0.orig/arch/powerpc/kvm/book3s_emulate.c 2017-10-24 16:34:51.000000000 +1100 +++ linux-4.4.0/arch/powerpc/kvm/book3s_emulate.c 2017-10-24 16:36:02.906876971 +1100 @@ -580,7 +580,7 @@ *spr_val = vcpu->arch.spurr; break; case SPRN_VTB: - *spr_val = vcpu->arch.vtb; + *spr_val = to_book3s(vcpu)->vtb; break; case SPRN_IC: *spr_val = vcpu->arch.ic; diff -ur linux-4.4.0.orig/arch/powerpc/kvm/book3s_hv.c linux-4.4.0/arch/powerpc/kvm/book3s_hv.c --- linux-4.4.0.orig/arch/powerpc/kvm/book3s_hv.c 2017-10-24 16:34:51.000000000 +1100 +++ linux-4.4.0/arch/powerpc/kvm/book3s_hv.c 2017-10-24 16:36:02.910877064 +1100 @@ -1101,6 +1101,9 @@ case KVM_REG_PPC_DPDES: *val = get_reg_val(id, vcpu->arch.vcore->dpdes); break; + case KVM_REG_PPC_VTB: + *val = get_reg_val(id, vcpu->arch.vcore->vtb); + break; case KVM_REG_PPC_DAWR: *val = get_reg_val(id, vcpu->arch.dawr); break; @@ -1296,6 +1299,9 @@ case KVM_REG_PPC_DPDES: vcpu->arch.vcore->dpdes = set_reg_val(id, *val); break; + case KVM_REG_PPC_VTB: + vcpu->arch.vcore->vtb = set_reg_val(id, *val); + break; case KVM_REG_PPC_DAWR: vcpu->arch.dawr = set_reg_val(id, *val); break; @@ -2122,9 +2128,11 @@ pvc->lpcr != vc->lpcr) return false; - /* P8 guest with > 1 thread per core would see wrong TIR value */ - if (cpu_has_feature(CPU_FTR_ARCH_207S) && - (vc->num_threads > 1 || pvc->num_threads > 1)) + /* + * P8 guests can't do piggybacking, because then the + * VTB would be shared between the vcpus. + */ + if (cpu_has_feature(CPU_FTR_ARCH_207S)) return false; n_thr = cip->subcore_threads[sub] + pvc->num_threads; diff -ur linux-4.4.0.orig/arch/powerpc/kvm/book3s_hv_rmhandlers.S linux-4.4.0/arch/powerpc/kvm/book3s_hv_rmhandlers.S --- linux-4.4.0.orig/arch/powerpc/kvm/book3s_hv_rmhandlers.S 2017-10-24 16:34:51.000000000 +1100 +++ linux-4.4.0/arch/powerpc/kvm/book3s_hv_rmhandlers.S 2017-10-24 16:36:02.910877064 +1100 @@ -622,9 +622,11 @@ 38: BEGIN_FTR_SECTION - /* DPDES is shared between threads */ + /* DPDES and VTB are shared between threads */ ld r8, VCORE_DPDES(r5) + ld r7, VCORE_VTB(r5) mtspr SPRN_DPDES, r8 + mtspr SPRN_VTB, r7 END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S) /* Mark the subcore state as inside guest */ @@ -794,10 +796,8 @@ mtspr SPRN_CIABR, r7 mtspr SPRN_TAR, r8 ld r5, VCPU_IC(r4) - ld r6, VCPU_VTB(r4) - mtspr SPRN_IC, r5 - mtspr SPRN_VTB, r6 ld r8, VCPU_EBBHR(r4) + mtspr SPRN_IC, r5 mtspr SPRN_EBBHR, r8 ld r5, VCPU_EBBRR(r4) ld r6, VCPU_BESCR(r4) @@ -1278,10 +1278,8 @@ 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) mfspr r8, SPRN_EBBHR std r8, VCPU_EBBHR(r9) @@ -1518,9 +1516,11 @@ isync BEGIN_FTR_SECTION - /* DPDES is shared between threads */ + /* DPDES and VTB are shared between threads */ mfspr r7, SPRN_DPDES + mfspr r8, SPRN_VTB std r7, VCORE_DPDES(r5) + std r8, VCORE_VTB(r5) /* clear DPDES so we don't get guest doorbells in the host */ li r8, 0 mtspr SPRN_DPDES, r8 diff -ur linux-4.4.0.orig/arch/powerpc/kvm/book3s_pr.c linux-4.4.0/arch/powerpc/kvm/book3s_pr.c --- linux-4.4.0.orig/arch/powerpc/kvm/book3s_pr.c 2017-10-24 16:34:51.000000000 +1100 +++ linux-4.4.0/arch/powerpc/kvm/book3s_pr.c 2017-10-24 16:36:02.910877064 +1100 @@ -226,7 +226,7 @@ */ vcpu->arch.purr += get_tb() - vcpu->arch.entry_tb; vcpu->arch.spurr += get_tb() - vcpu->arch.entry_tb; - vcpu->arch.vtb += get_vtb() - vcpu->arch.entry_vtb; + to_book3s(vcpu)->vtb += get_vtb() - vcpu->arch.entry_vtb; if (cpu_has_feature(CPU_FTR_ARCH_207S)) vcpu->arch.ic += mfspr(SPRN_IC) - vcpu->arch.entry_ic; svcpu->in_use = false; @@ -1325,6 +1325,9 @@ case KVM_REG_PPC_HIOR: *val = get_reg_val(id, to_book3s(vcpu)->hior); break; + case KVM_REG_PPC_VTB: + *val = get_reg_val(id, to_book3s(vcpu)->vtb); + break; case KVM_REG_PPC_LPCR: case KVM_REG_PPC_LPCR_64: /* @@ -1361,6 +1364,9 @@ to_book3s(vcpu)->hior = set_reg_val(id, *val); to_book3s(vcpu)->hior_explicit = true; break; + case KVM_REG_PPC_VTB: + to_book3s(vcpu)->vtb = set_reg_val(id, *val); + break; case KVM_REG_PPC_LPCR: case KVM_REG_PPC_LPCR_64: kvmppc_set_lpcr_pr(vcpu, set_reg_val(id, *val));