All of lore.kernel.org
 help / color / mirror / Atom feed
* [[RFC] KVM-S390: Provide guest TOD Clock Get/Set Controls
@ 2014-09-19 14:19 Jason J. Herne
  2014-09-19 18:51 ` Christian Borntraeger
  0 siblings, 1 reply; 7+ messages in thread
From: Jason J. Herne @ 2014-09-19 14:19 UTC (permalink / raw)
  To: kvm, borntraeger, cornelia.huck, aik, agraf; +Cc: Jason J. Herne

From: "Jason J. Herne" <jjherne@us.ibm.com>

Enable KVM_SET_CLOCK and KVM_GET_CLOCK Ioctls on S390 for managing guest TOD
clock value.

we add the KVM_CLOCK_FORWARD_ONLY flag to indicate to KVM_SET_CLOCK that the
given clock value should only be set if it is >= the current guest TOD clock
value. This guarantees a monotonically increasing time.

NOTE: In the event that the KVM_CLOCK_FORWARD_ONLY flag is set and the given
time would cause the guest time to jump backward, then we set the guest TOD
clock equal to the host TOD clock. Does this behavior make sense, or is it too
weird? I could believe that other architectures might not want this exact
behavior. Instead they might prefer to implement the function such that an
error code is returned instead of syncing the guest time to host time? In that
case S390 would need another bit KVM_CLOCK_SET_TO_HOST which we could call to
sync host time when the preferred guest time value would otherwise violate
the monotonic property of the KVM_CLOCK_FORWARD_ONLY flag.

Signed-off-by: Jason J. Herne <jjherne@us.ibm.com>
---
 Documentation/virtual/kvm/api.txt |  5 +++
 arch/s390/kvm/kvm-s390.c          | 80 +++++++++++++++++++++++++++++++++++++++
 include/uapi/linux/kvm.h          |  3 ++
 3 files changed, 88 insertions(+)

diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index beae3fd..615c2e4 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -779,6 +779,11 @@ struct kvm_clock_data {
 	__u32 pad[9];
 };
 
+S390: KVM_CLOCK_FORWARD_ONLY is used by KVM_SET_CLOCK to indicate that the guest
+TOD clock should not be allowed to jump back in time. This flag guarantees a
+monotonically increasing guest clock. If the clock value specified would cause
+the guest to jump back in time then the guest TOD clock is set to the host
+TOD clock value.
 
 4.31 KVM_GET_VCPU_EVENTS
 
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index 81b0e11..2450db3 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -31,6 +31,7 @@
 #include <asm/switch_to.h>
 #include <asm/facility.h>
 #include <asm/sclp.h>
+#include<asm/timex.h>
 #include "kvm-s390.h"
 #include "gaccess.h"
 
@@ -169,6 +170,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
 	case KVM_CAP_S390_IRQCHIP:
 	case KVM_CAP_VM_ATTRIBUTES:
 	case KVM_CAP_MP_STATE:
+	case KVM_CAP_ADJUST_CLOCK:
 		r = 1;
 		break;
 	case KVM_CAP_NR_VCPUS:
@@ -338,6 +340,63 @@ static int kvm_s390_vm_has_attr(struct kvm *kvm, struct kvm_device_attr *attr)
 	return ret;
 }
 
+static int kvm_s390_get_guest_tod(struct kvm *kvm, struct kvm_clock_data *user_clock)
+{
+	u64 current_host_tod;
+	u64 epoch = 0;
+	struct kvm_vcpu *vcpu;
+	unsigned int vcpu_idx;
+	int r;
+
+	/* All vcpu's epochs are in sync. Just Grab the 1st one */
+	kvm_for_each_vcpu(vcpu_idx, vcpu, kvm)
+	{
+		epoch = vcpu->arch.sie_block->epoch;
+		break;
+	}
+
+	r = store_tod_clock(&current_host_tod);
+	if (r)
+		return r;
+
+	user_clock->clock = current_host_tod + epoch;
+	return 0;
+}
+
+/*
+Set the guest's effective TOD clock to the given value. The guest's
+TOD clock is determined by the following formula: gtod = host_tod + epoch.
+NOTE: Even though the epoch value is associated with a "vcpu", there is only
+one TOD clock and epoch value per guest.  All vcpu's epoch values must be kept
+synchronized.
+NOTE: The KVM_CLOCK_FORWARD_ONLY flag is used to indicate that the guest clock
+should only be set to the provided value if doing so does not cause guest time
+to jump backwards. In this case we zero the epoch thereby making the guest TOD
+clock equal to the host TOD clock.
+*/
+static int kvm_s390_set_guest_tod(struct kvm *kvm, struct kvm_clock_data *user_clock)
+{
+	u64 current_host_tod, epoch;
+	struct kvm_vcpu *vcpu;
+	unsigned int vcpu_idx;
+	int r;
+
+	r = store_tod_clock(&current_host_tod);
+	if (r)
+		return r;
+
+    if ((user_clock->flags & KVM_CLOCK_FORWARD_ONLY) &&
+        (current_host_tod > user_clock->clock))
+        epoch = 0;
+    else
+	    epoch = user_clock->clock - current_host_tod;
+
+	kvm_for_each_vcpu(vcpu_idx, vcpu, kvm)
+		vcpu->arch.sie_block->epoch = epoch;
+
+	return 0;
+}
+
 long kvm_arch_vm_ioctl(struct file *filp,
 		       unsigned int ioctl, unsigned long arg)
 {
@@ -397,6 +456,27 @@ long kvm_arch_vm_ioctl(struct file *filp,
 		r = kvm_s390_vm_has_attr(kvm, &attr);
 		break;
 	}
+	case KVM_GET_CLOCK: {
+		struct kvm_clock_data user_clock;
+
+		r = kvm_s390_get_guest_tod(kvm, &user_clock);
+		if (r)
+			break;
+
+		if (copy_to_user(argp, &user_clock, sizeof(user_clock)))
+			r = -EFAULT;
+
+		break;
+	}
+	case KVM_SET_CLOCK: {
+		struct kvm_clock_data user_clock;
+
+		r = -EFAULT;
+		if (copy_from_user(&user_clock, argp, sizeof(struct kvm_clock_data)))
+			break;
+		r = kvm_s390_set_guest_tod(kvm, &user_clock);
+		break;
+	}
 	default:
 		r = -ENOTTY;
 	}
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index cf3a2ff..a832b6a 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -857,6 +857,9 @@ struct kvm_irqfd {
 	__u8  pad[16];
 };
 
+/* Flag definitions for kvm_clock_data.flags */
+#define KVM_CLOCK_FORWARD_ONLY (1 << 0)
+
 struct kvm_clock_data {
 	__u64 clock;
 	__u32 flags;
-- 
1.8.3.2


^ permalink raw reply related	[flat|nested] 7+ messages in thread
* Re: [[RFC] KVM-S390: Provide guest TOD Clock Get/Set Controls
@ 2014-10-08 14:22 Jason J. Herne
  0 siblings, 0 replies; 7+ messages in thread
From: Jason J. Herne @ 2014-10-08 14:22 UTC (permalink / raw)
  To: kvm, Christian Borntraeger, Alexander Graf, aik, Cornelia Huck

This is a reply to the following thread:
http://www.spinics.net/lists/kvm/msg108448.html

I'm sending it in this fashion because my normal mail client
is not allowing me to send it in plain text and the html is
getting rejected by the mailing list. Sorry to those of you who
received both this and the original.


Ping. Does anyone feel strongly about this issue? I'm interested in
opinions so we can get s390 TOD clock migration working :).

We need to decide which interface to use, s390 specific ioctl or
KVM_SET_CLOCK.

Then we need to decide if we're going to snap a guest clock forward
on the resume of a "suspend to disk" type operation. The alternative
is to fix up the guest TOD value such that the guest notices no
change of time, which as Christian points out, seems wrong. Unless we
really want to show no time change and force the guest to use ntp to
figure out that he is behind.

-- 
-- Jason J. Herne (jjherne@linux.vnet.ibm.com)


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2014-10-09  8:12 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-09-19 14:19 [[RFC] KVM-S390: Provide guest TOD Clock Get/Set Controls Jason J. Herne
2014-09-19 18:51 ` Christian Borntraeger
2014-09-19 20:38   ` Alexander Graf
2014-09-22  9:08     ` Christian Borntraeger
     [not found]       ` <OFBB97D6FC.48AF23F2-ON87257D6B.004D1813-85257D6B.004DC089@us.ibm.com>
2014-10-08 14:55         ` Alexander Graf
2014-10-09  8:12           ` Christian Borntraeger
  -- strict thread matches above, loose matches on Subject: below --
2014-10-08 14:22 Jason J. Herne

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.