KVM: PPC: Book3S HV: Enable migration of decrementer register

"Linux Kernel Mailing List" <[email protected]> Sat, 10 Feb 2018 22:00:24 +0000 (UTC)
Newsgroups gmane.linux.kernel.commits.head
Message-ID <[email protected]>
Web:        https://git.kernel.org/torvalds/c/5855564c8ab2d9cefca7b2933bd19818eb795e40
Commit:     5855564c8ab2d9cefca7b2933bd19818eb795e40
Parent:     1627301020cb460f5a74e13c291f8db3b2a8062e
Refname:    refs/heads/master
Author:     Paul Mackerras <[email protected]>
AuthorDate: Fri Jan 12 20:55:20 2018 +1100
Committer:  Paul Mackerras <[email protected]>
CommitDate: Tue Jan 16 11:54:45 2018 +1100

    KVM: PPC: Book3S HV: Enable migration of decrementer register
    
    This adds a register identifier for use with the one_reg interface
    to allow the decrementer expiry time to be read and written by
    userspace.  The decrementer expiry time is in guest timebase units
    and is equal to the sum of the decrementer and the guest timebase.
    (The expiry time is used rather than the decrementer value itself
    because the expiry time is not constantly changing, though the
    decrementer value is, while the guest vcpu is not running.)
    
    Without this, a guest vcpu migrated to a new host will see its
    decrementer set to some random value.  On POWER8 and earlier, the
    decrementer is 32 bits wide and counts down at 512MHz, so the
    guest vcpu will potentially see no decrementer interrupts for up
    to about 4 seconds, which will lead to a stall.  With POWER9, the
    decrementer is now 56 bits side, so the stall can be much longer
    (up to 2.23 years) and more noticeable.
    
    To help work around the problem in cases where userspace has not been
    updated to migrate the decrementer expiry time, we now set the
    default decrementer expiry at vcpu creation time to the current time
    rather than the maximum possible value.  This should mean an
    immediate decrementer interrupt when a migrated vcpu starts
    running.  In cases where the decrementer is 32 bits wide and more
    than 4 seconds elapse between the creation of the vcpu and when it
    first runs, the decrementer would have wrapped around to positive
    values and there may still be a stall - but this is no worse than
    the current situation.  In the large-decrementer case, we are sure
    to get an immediate decrementer interrupt (assuming the time from
    vcpu creation to first run is less than 2.23 years) and we thus
    avoid a very long stall.
    
    Signed-off-by: Paul Mackerras <[email protected]>
---
 Documentation/virtual/kvm/api.txt   | 1 +
 arch/powerpc/include/uapi/asm/kvm.h | 2 ++
 arch/powerpc/kvm/book3s_hv.c        | 8 ++++++++
 arch/powerpc/kvm/powerpc.c          | 2 +-
 4 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index f670e4b9e7f3..c6f9eebb79f2 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -1841,6 +1841,7 @@ registers, find a list below:
   PPC	| KVM_REG_PPC_DBSR              | 32
   PPC   | KVM_REG_PPC_TIDR              | 64
   PPC   | KVM_REG_PPC_PSSCR             | 64
+  PPC   | KVM_REG_PPC_DEC_EXPIRY        | 64
   PPC   | KVM_REG_PPC_TM_GPR0           | 64
           ...
   PPC   | KVM_REG_PPC_TM_GPR31          | 64
diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h
index 61d6049f4c1e..8aaec831053a 100644
--- a/arch/powerpc/include/uapi/asm/kvm.h
+++ b/arch/powerpc/include/uapi/asm/kvm.h
@@ -607,6 +607,8 @@ struct kvm_ppc_rmmu_info {
 #define KVM_REG_PPC_TIDR	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xbc)
 #define KVM_REG_PPC_PSSCR	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xbd)
 
+#define KVM_REG_PPC_DEC_EXPIRY	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xbe)
+
 /* Transactional Memory checkpointed state:
  * This is all GPRs, all VSX regs and a subset of SPRs
  */
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index c4f0bebfc5ba..b2d448c75008 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -1497,6 +1497,10 @@ static int kvmppc_get_one_reg_hv(struct kvm_vcpu *vcpu, u64 id,
 	case KVM_REG_PPC_ARCH_COMPAT:
 		*val = get_reg_val(id, vcpu->arch.vcore->arch_compat);
 		break;
+	case KVM_REG_PPC_DEC_EXPIRY:
+		*val = get_reg_val(id, vcpu->arch.dec_expires +
+				   vcpu->arch.vcore->tb_offset);
+		break;
 	default:
 		r = -EINVAL;
 		break;
@@ -1724,6 +1728,10 @@ static int kvmppc_set_one_reg_hv(struct kvm_vcpu *vcpu, u64 id,
 	case KVM_REG_PPC_ARCH_COMPAT:
 		r = kvmppc_set_arch_compat(vcpu, set_reg_val(id, *val));
 		break;
+	case KVM_REG_PPC_DEC_EXPIRY:
+		vcpu->arch.dec_expires = set_reg_val(id, *val) -
+			vcpu->arch.vcore->tb_offset;
+		break;
 	default:
 		r = -EINVAL;
 		break;
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index c2c7ef330553..7c9e45f54186 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -758,7 +758,7 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
 
 	hrtimer_init(&vcpu->arch.dec_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS);
 	vcpu->arch.dec_timer.function = kvmppc_decrementer_wakeup;
-	vcpu->arch.dec_expires = ~(u64)0;
+	vcpu->arch.dec_expires = get_tb();
 
 #ifdef CONFIG_KVM_EXIT_TIMING
 	mutex_init(&vcpu->arch.exit_timing_lock);
--
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html