aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2014-03-24 19:47:07 -0400
committerPaul Mackerras <paulus@samba.org>2014-03-29 04:58:39 -0400
commitc5fb80d3b24f6280bd6f608d8f2a02139a0fabaf (patch)
tree10489a033c49027a48c20161dd23a2270244febd
parent797f9c07eb4cbc2d0ff27fac165a0b885da38840 (diff)
KVM: PPC: Book3S HV: Fix decrementer timeouts with non-zero TB offset
Commit c7699822bc21 ("KVM: PPC: Book3S HV: Make physical thread 0 do the MMU switching") reordered the guest entry/exit code so that most of the guest register save/restore code happened in guest MMU context. A side effect of that is that the timebase still contains the guest timebase value at the point where we compute and use vcpu->arch.dec_expires, and therefore that is now a guest timebase value rather than a host timebase value. That in turn means that the timeouts computed in kvmppc_set_timer() are wrong if the timebase offset for the guest is non-zero. The consequence of that is things such as "sleep 1" in a guest after migration may sleep for much longer than they should. This fixes the problem by converting between guest and host timebase values as necessary, by adding or subtracting the timebase offset. This also fixes an incorrect comment. Signed-off-by: Paul Mackerras <paulus@samba.org> Acked-by: Scott Wood <scottwood@freescale.com>
-rw-r--r--arch/powerpc/kvm/book3s_hv_rmhandlers.S10
1 files changed, 9 insertions, 1 deletions
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index 61190ddd9f3b..42bd2e694b1b 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -841,6 +841,10 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S)
841 * Set the decrementer to the guest decrementer. 841 * Set the decrementer to the guest decrementer.
842 */ 842 */
843 ld r8,VCPU_DEC_EXPIRES(r4) 843 ld r8,VCPU_DEC_EXPIRES(r4)
844 /* r8 is a host timebase value here, convert to guest TB */
845 ld r5,HSTATE_KVM_VCORE(r13)
846 ld r6,VCORE_TB_OFFSET(r5)
847 add r8,r8,r6
844 mftb r7 848 mftb r7
845 subf r3,r7,r8 849 subf r3,r7,r8
846 mtspr SPRN_DEC,r3 850 mtspr SPRN_DEC,r3
@@ -1204,6 +1208,10 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_201)
1204 mftb r6 1208 mftb r6
1205 extsw r5,r5 1209 extsw r5,r5
1206 add r5,r5,r6 1210 add r5,r5,r6
1211 /* r5 is a guest timebase value here, convert to host TB */
1212 ld r3,HSTATE_KVM_VCORE(r13)
1213 ld r4,VCORE_TB_OFFSET(r3)
1214 subf r5,r4,r5
1207 std r5,VCPU_DEC_EXPIRES(r9) 1215 std r5,VCPU_DEC_EXPIRES(r9)
1208 1216
1209BEGIN_FTR_SECTION 1217BEGIN_FTR_SECTION
@@ -1479,7 +1487,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
1479 ld r8,VCORE_TB_OFFSET(r5) 1487 ld r8,VCORE_TB_OFFSET(r5)
1480 cmpdi r8,0 1488 cmpdi r8,0
1481 beq 17f 1489 beq 17f
1482 mftb r6 /* current host timebase */ 1490 mftb r6 /* current guest timebase */
1483 subf r8,r8,r6 1491 subf r8,r8,r6
1484 mtspr SPRN_TBU40,r8 /* update upper 40 bits */ 1492 mtspr SPRN_TBU40,r8 /* update upper 40 bits */
1485 mftb r7 /* check if lower 24 bits overflowed */ 1493 mftb r7 /* check if lower 24 bits overflowed */