All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/7] KVM: Hyper-V SynIC timers migration fixes
@ 2015-12-28 15:27 ` Andrey Smetanin
  0 siblings, 0 replies; 22+ messages in thread
From: Andrey Smetanin @ 2015-12-28 15:27 UTC (permalink / raw)
  To: kvm; +Cc: Gleb Natapov, Paolo Bonzini, Roman Kagan, Denis V. Lunev, qemu-devel

During testing of Windows 2012R2 guest migration with
Hyper-V SynIC timers enabled we found several bugs
which lead to restoring guest in a hung state.

This patch series provides several fixes to make the
migration of guest with Hyper-V SynIC timers enabled
succeed.

The series applies on top of
'kvm/x86: Remove Hyper-V SynIC timer stopping'
previously sent.

Changes v2:
* fix incorrect logical operation for one-shot timers
* drop stimer->count == 0 inside stimer_start()
* comment stimer_start() assumtions

Signed-off-by: Andrey Smetanin <asmetanin@virtuozzo.com>
Reviewed-by: Roman Kagan <rkagan@virtuozzo.com>
CC: Gleb Natapov <gleb@kernel.org>
CC: Paolo Bonzini <pbonzini@redhat.com>
CC: Roman Kagan <rkagan@virtuozzo.com>
CC: Denis V. Lunev <den@openvz.org>
CC: qemu-devel@nongnu.org

Andrey Smetanin (7):
  kvm/x86: Hyper-V timers fix incorrect logical operation
  kvm/x86: Drop stimer_stop() function
  kvm/x86: Hyper-V unify stimer_start() and stimer_restart()
  kvm/x86: Reorg stimer_expiration() to better control timer restart
  kvm/x86: Hyper-V fix SynIC timer disabling condition
  kvm/x86: Skip SynIC vector check for QEMU side
  kvm/x86: Update SynIC timers on guest entry only

 arch/x86/kvm/hyperv.c | 119 ++++++++++++++++++++++++--------------------------
 arch/x86/kvm/x86.c    |   6 +++
 2 files changed, 63 insertions(+), 62 deletions(-)

-- 
2.4.3


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

* [Qemu-devel] [PATCH v2 0/7] KVM: Hyper-V SynIC timers migration fixes
@ 2015-12-28 15:27 ` Andrey Smetanin
  0 siblings, 0 replies; 22+ messages in thread
From: Andrey Smetanin @ 2015-12-28 15:27 UTC (permalink / raw)
  To: kvm; +Cc: Gleb Natapov, Paolo Bonzini, qemu-devel, Roman Kagan, Denis V. Lunev

During testing of Windows 2012R2 guest migration with
Hyper-V SynIC timers enabled we found several bugs
which lead to restoring guest in a hung state.

This patch series provides several fixes to make the
migration of guest with Hyper-V SynIC timers enabled
succeed.

The series applies on top of
'kvm/x86: Remove Hyper-V SynIC timer stopping'
previously sent.

Changes v2:
* fix incorrect logical operation for one-shot timers
* drop stimer->count == 0 inside stimer_start()
* comment stimer_start() assumtions

Signed-off-by: Andrey Smetanin <asmetanin@virtuozzo.com>
Reviewed-by: Roman Kagan <rkagan@virtuozzo.com>
CC: Gleb Natapov <gleb@kernel.org>
CC: Paolo Bonzini <pbonzini@redhat.com>
CC: Roman Kagan <rkagan@virtuozzo.com>
CC: Denis V. Lunev <den@openvz.org>
CC: qemu-devel@nongnu.org

Andrey Smetanin (7):
  kvm/x86: Hyper-V timers fix incorrect logical operation
  kvm/x86: Drop stimer_stop() function
  kvm/x86: Hyper-V unify stimer_start() and stimer_restart()
  kvm/x86: Reorg stimer_expiration() to better control timer restart
  kvm/x86: Hyper-V fix SynIC timer disabling condition
  kvm/x86: Skip SynIC vector check for QEMU side
  kvm/x86: Update SynIC timers on guest entry only

 arch/x86/kvm/hyperv.c | 119 ++++++++++++++++++++++++--------------------------
 arch/x86/kvm/x86.c    |   6 +++
 2 files changed, 63 insertions(+), 62 deletions(-)

-- 
2.4.3

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

* [PATCH v2 1/7] kvm/x86: Hyper-V timers fix incorrect logical operation
  2015-12-28 15:27 ` [Qemu-devel] " Andrey Smetanin
@ 2015-12-28 15:27   ` Andrey Smetanin
  -1 siblings, 0 replies; 22+ messages in thread
From: Andrey Smetanin @ 2015-12-28 15:27 UTC (permalink / raw)
  To: kvm; +Cc: Gleb Natapov, Paolo Bonzini, Roman Kagan, Denis V. Lunev, qemu-devel

Signed-off-by: Andrey Smetanin <asmetanin@virtuozzo.com>
Reviewed-by: Roman Kagan <rkagan@virtuozzo.com>
CC: Gleb Natapov <gleb@kernel.org>
CC: Paolo Bonzini <pbonzini@redhat.com>
CC: Roman Kagan <rkagan@virtuozzo.com>
CC: Denis V. Lunev <den@openvz.org>
CC: qemu-devel@nongnu.org

---
 arch/x86/kvm/hyperv.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index f34f666..e4ef13a 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -583,7 +583,7 @@ static void stimer_expiration(struct kvm_vcpu_hv_stimer *stimer)
 {
 	stimer_send_msg(stimer);
 	if (!(stimer->config & HV_STIMER_PERIODIC))
-		stimer->config |= ~HV_STIMER_ENABLE;
+		stimer->config &= ~HV_STIMER_ENABLE;
 	else
 		stimer_restart(stimer);
 }
-- 
2.4.3


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

* [Qemu-devel] [PATCH v2 1/7] kvm/x86: Hyper-V timers fix incorrect logical operation
@ 2015-12-28 15:27   ` Andrey Smetanin
  0 siblings, 0 replies; 22+ messages in thread
From: Andrey Smetanin @ 2015-12-28 15:27 UTC (permalink / raw)
  To: kvm; +Cc: Gleb Natapov, Paolo Bonzini, qemu-devel, Roman Kagan, Denis V. Lunev

Signed-off-by: Andrey Smetanin <asmetanin@virtuozzo.com>
Reviewed-by: Roman Kagan <rkagan@virtuozzo.com>
CC: Gleb Natapov <gleb@kernel.org>
CC: Paolo Bonzini <pbonzini@redhat.com>
CC: Roman Kagan <rkagan@virtuozzo.com>
CC: Denis V. Lunev <den@openvz.org>
CC: qemu-devel@nongnu.org

---
 arch/x86/kvm/hyperv.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index f34f666..e4ef13a 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -583,7 +583,7 @@ static void stimer_expiration(struct kvm_vcpu_hv_stimer *stimer)
 {
 	stimer_send_msg(stimer);
 	if (!(stimer->config & HV_STIMER_PERIODIC))
-		stimer->config |= ~HV_STIMER_ENABLE;
+		stimer->config &= ~HV_STIMER_ENABLE;
 	else
 		stimer_restart(stimer);
 }
-- 
2.4.3

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

* [PATCH v2 2/7] kvm/x86: Drop stimer_stop() function
  2015-12-28 15:27 ` [Qemu-devel] " Andrey Smetanin
@ 2015-12-28 15:27   ` Andrey Smetanin
  -1 siblings, 0 replies; 22+ messages in thread
From: Andrey Smetanin @ 2015-12-28 15:27 UTC (permalink / raw)
  To: kvm; +Cc: Gleb Natapov, Paolo Bonzini, Roman Kagan, Denis V. Lunev, qemu-devel

The function stimer_stop() is called in one place
so remove the function and replace it's call by function
content.

Signed-off-by: Andrey Smetanin <asmetanin@virtuozzo.com>
Reviewed-by: Roman Kagan <rkagan@virtuozzo.com>
CC: Gleb Natapov <gleb@kernel.org>
CC: Paolo Bonzini <pbonzini@redhat.com>
CC: Roman Kagan <rkagan@virtuozzo.com>
CC: Denis V. Lunev <den@openvz.org>
CC: qemu-devel@nongnu.org
---
 arch/x86/kvm/hyperv.c | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index e4ef13a..6b2ed93 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -400,16 +400,11 @@ static void stimer_mark_expired(struct kvm_vcpu_hv_stimer *stimer,
 		kvm_vcpu_kick(vcpu);
 }
 
-static void stimer_stop(struct kvm_vcpu_hv_stimer *stimer)
-{
-	hrtimer_cancel(&stimer->timer);
-}
-
 static void stimer_cleanup(struct kvm_vcpu_hv_stimer *stimer)
 {
 	struct kvm_vcpu *vcpu = stimer_to_vcpu(stimer);
 
-	stimer_stop(stimer);
+	hrtimer_cancel(&stimer->timer);
 	clear_bit(stimer->index,
 		  vcpu_to_hv_vcpu(vcpu)->stimer_pending_bitmap);
 	stimer->msg_pending = false;
-- 
2.4.3


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

* [Qemu-devel] [PATCH v2 2/7] kvm/x86: Drop stimer_stop() function
@ 2015-12-28 15:27   ` Andrey Smetanin
  0 siblings, 0 replies; 22+ messages in thread
From: Andrey Smetanin @ 2015-12-28 15:27 UTC (permalink / raw)
  To: kvm; +Cc: Gleb Natapov, Paolo Bonzini, qemu-devel, Roman Kagan, Denis V. Lunev

The function stimer_stop() is called in one place
so remove the function and replace it's call by function
content.

Signed-off-by: Andrey Smetanin <asmetanin@virtuozzo.com>
Reviewed-by: Roman Kagan <rkagan@virtuozzo.com>
CC: Gleb Natapov <gleb@kernel.org>
CC: Paolo Bonzini <pbonzini@redhat.com>
CC: Roman Kagan <rkagan@virtuozzo.com>
CC: Denis V. Lunev <den@openvz.org>
CC: qemu-devel@nongnu.org
---
 arch/x86/kvm/hyperv.c | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index e4ef13a..6b2ed93 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -400,16 +400,11 @@ static void stimer_mark_expired(struct kvm_vcpu_hv_stimer *stimer,
 		kvm_vcpu_kick(vcpu);
 }
 
-static void stimer_stop(struct kvm_vcpu_hv_stimer *stimer)
-{
-	hrtimer_cancel(&stimer->timer);
-}
-
 static void stimer_cleanup(struct kvm_vcpu_hv_stimer *stimer)
 {
 	struct kvm_vcpu *vcpu = stimer_to_vcpu(stimer);
 
-	stimer_stop(stimer);
+	hrtimer_cancel(&stimer->timer);
 	clear_bit(stimer->index,
 		  vcpu_to_hv_vcpu(vcpu)->stimer_pending_bitmap);
 	stimer->msg_pending = false;
-- 
2.4.3

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

* [PATCH v2 3/7] kvm/x86: Hyper-V unify stimer_start() and stimer_restart()
  2015-12-28 15:27 ` [Qemu-devel] " Andrey Smetanin
@ 2015-12-28 15:27   ` Andrey Smetanin
  -1 siblings, 0 replies; 22+ messages in thread
From: Andrey Smetanin @ 2015-12-28 15:27 UTC (permalink / raw)
  To: kvm; +Cc: Gleb Natapov, Paolo Bonzini, Roman Kagan, Denis V. Lunev, qemu-devel

This will be used in future to start Hyper-V SynIC timer
in several places by one logic in one function.

Changes v2:
* drop stimer->count == 0 check inside stimer_start()
* comment stimer_start() assumptions

Signed-off-by: Andrey Smetanin <asmetanin@virtuozzo.com>
Reviewed-by: Roman Kagan <rkagan@virtuozzo.com>
CC: Gleb Natapov <gleb@kernel.org>
CC: Paolo Bonzini <pbonzini@redhat.com>
CC: Roman Kagan <rkagan@virtuozzo.com>
CC: Denis V. Lunev <den@openvz.org>
CC: qemu-devel@nongnu.org
---
 arch/x86/kvm/hyperv.c | 43 ++++++++++++++++++++-----------------------
 1 file changed, 20 insertions(+), 23 deletions(-)

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index 6b2ed93..0dd7d17 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -408,6 +408,7 @@ static void stimer_cleanup(struct kvm_vcpu_hv_stimer *stimer)
 	clear_bit(stimer->index,
 		  vcpu_to_hv_vcpu(vcpu)->stimer_pending_bitmap);
 	stimer->msg_pending = false;
+	stimer->exp_time = 0;
 }
 
 static enum hrtimer_restart stimer_timer_callback(struct hrtimer *timer)
@@ -420,24 +421,11 @@ static enum hrtimer_restart stimer_timer_callback(struct hrtimer *timer)
 	return HRTIMER_NORESTART;
 }
 
-static void stimer_restart(struct kvm_vcpu_hv_stimer *stimer)
-{
-	u64 time_now;
-	ktime_t ktime_now;
-	u64 remainder;
-
-	time_now = get_time_ref_counter(stimer_to_vcpu(stimer)->kvm);
-	ktime_now = ktime_get();
-
-	div64_u64_rem(time_now - stimer->exp_time, stimer->count, &remainder);
-	stimer->exp_time = time_now + (stimer->count - remainder);
-
-	hrtimer_start(&stimer->timer,
-		      ktime_add_ns(ktime_now,
-				   100 * (stimer->exp_time - time_now)),
-		      HRTIMER_MODE_ABS);
-}
-
+/*
+ * stimer_start() assumptions:
+ * a) stimer->count is not equal to 0
+ * b) stimer->config has HV_STIMER_ENABLE flag
+ */
 static int stimer_start(struct kvm_vcpu_hv_stimer *stimer)
 {
 	u64 time_now;
@@ -447,12 +435,21 @@ static int stimer_start(struct kvm_vcpu_hv_stimer *stimer)
 	ktime_now = ktime_get();
 
 	if (stimer->config & HV_STIMER_PERIODIC) {
-		if (stimer->count == 0)
-			return -EINVAL;
+		if (stimer->exp_time) {
+			if (time_now >= stimer->exp_time) {
+				u64 remainder;
+
+				div64_u64_rem(time_now - stimer->exp_time,
+					      stimer->count, &remainder);
+				stimer->exp_time =
+					time_now + (stimer->count - remainder);
+			}
+		} else
+			stimer->exp_time = time_now + stimer->count;
 
-		stimer->exp_time = time_now + stimer->count;
 		hrtimer_start(&stimer->timer,
-			      ktime_add_ns(ktime_now, 100 * stimer->count),
+			      ktime_add_ns(ktime_now,
+					   100 * (stimer->exp_time - time_now)),
 			      HRTIMER_MODE_ABS);
 		return 0;
 	}
@@ -580,7 +577,7 @@ static void stimer_expiration(struct kvm_vcpu_hv_stimer *stimer)
 	if (!(stimer->config & HV_STIMER_PERIODIC))
 		stimer->config &= ~HV_STIMER_ENABLE;
 	else
-		stimer_restart(stimer);
+		stimer_start(stimer);
 }
 
 void kvm_hv_process_stimers(struct kvm_vcpu *vcpu)
-- 
2.4.3


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

* [Qemu-devel] [PATCH v2 3/7] kvm/x86: Hyper-V unify stimer_start() and stimer_restart()
@ 2015-12-28 15:27   ` Andrey Smetanin
  0 siblings, 0 replies; 22+ messages in thread
From: Andrey Smetanin @ 2015-12-28 15:27 UTC (permalink / raw)
  To: kvm; +Cc: Gleb Natapov, Paolo Bonzini, qemu-devel, Roman Kagan, Denis V. Lunev

This will be used in future to start Hyper-V SynIC timer
in several places by one logic in one function.

Changes v2:
* drop stimer->count == 0 check inside stimer_start()
* comment stimer_start() assumptions

Signed-off-by: Andrey Smetanin <asmetanin@virtuozzo.com>
Reviewed-by: Roman Kagan <rkagan@virtuozzo.com>
CC: Gleb Natapov <gleb@kernel.org>
CC: Paolo Bonzini <pbonzini@redhat.com>
CC: Roman Kagan <rkagan@virtuozzo.com>
CC: Denis V. Lunev <den@openvz.org>
CC: qemu-devel@nongnu.org
---
 arch/x86/kvm/hyperv.c | 43 ++++++++++++++++++++-----------------------
 1 file changed, 20 insertions(+), 23 deletions(-)

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index 6b2ed93..0dd7d17 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -408,6 +408,7 @@ static void stimer_cleanup(struct kvm_vcpu_hv_stimer *stimer)
 	clear_bit(stimer->index,
 		  vcpu_to_hv_vcpu(vcpu)->stimer_pending_bitmap);
 	stimer->msg_pending = false;
+	stimer->exp_time = 0;
 }
 
 static enum hrtimer_restart stimer_timer_callback(struct hrtimer *timer)
@@ -420,24 +421,11 @@ static enum hrtimer_restart stimer_timer_callback(struct hrtimer *timer)
 	return HRTIMER_NORESTART;
 }
 
-static void stimer_restart(struct kvm_vcpu_hv_stimer *stimer)
-{
-	u64 time_now;
-	ktime_t ktime_now;
-	u64 remainder;
-
-	time_now = get_time_ref_counter(stimer_to_vcpu(stimer)->kvm);
-	ktime_now = ktime_get();
-
-	div64_u64_rem(time_now - stimer->exp_time, stimer->count, &remainder);
-	stimer->exp_time = time_now + (stimer->count - remainder);
-
-	hrtimer_start(&stimer->timer,
-		      ktime_add_ns(ktime_now,
-				   100 * (stimer->exp_time - time_now)),
-		      HRTIMER_MODE_ABS);
-}
-
+/*
+ * stimer_start() assumptions:
+ * a) stimer->count is not equal to 0
+ * b) stimer->config has HV_STIMER_ENABLE flag
+ */
 static int stimer_start(struct kvm_vcpu_hv_stimer *stimer)
 {
 	u64 time_now;
@@ -447,12 +435,21 @@ static int stimer_start(struct kvm_vcpu_hv_stimer *stimer)
 	ktime_now = ktime_get();
 
 	if (stimer->config & HV_STIMER_PERIODIC) {
-		if (stimer->count == 0)
-			return -EINVAL;
+		if (stimer->exp_time) {
+			if (time_now >= stimer->exp_time) {
+				u64 remainder;
+
+				div64_u64_rem(time_now - stimer->exp_time,
+					      stimer->count, &remainder);
+				stimer->exp_time =
+					time_now + (stimer->count - remainder);
+			}
+		} else
+			stimer->exp_time = time_now + stimer->count;
 
-		stimer->exp_time = time_now + stimer->count;
 		hrtimer_start(&stimer->timer,
-			      ktime_add_ns(ktime_now, 100 * stimer->count),
+			      ktime_add_ns(ktime_now,
+					   100 * (stimer->exp_time - time_now)),
 			      HRTIMER_MODE_ABS);
 		return 0;
 	}
@@ -580,7 +577,7 @@ static void stimer_expiration(struct kvm_vcpu_hv_stimer *stimer)
 	if (!(stimer->config & HV_STIMER_PERIODIC))
 		stimer->config &= ~HV_STIMER_ENABLE;
 	else
-		stimer_restart(stimer);
+		stimer_start(stimer);
 }
 
 void kvm_hv_process_stimers(struct kvm_vcpu *vcpu)
-- 
2.4.3

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

* [PATCH v2 4/7] kvm/x86: Reorg stimer_expiration() to better control timer restart
  2015-12-28 15:27 ` [Qemu-devel] " Andrey Smetanin
@ 2015-12-28 15:27   ` Andrey Smetanin
  -1 siblings, 0 replies; 22+ messages in thread
From: Andrey Smetanin @ 2015-12-28 15:27 UTC (permalink / raw)
  To: kvm; +Cc: Gleb Natapov, Paolo Bonzini, Roman Kagan, Denis V. Lunev, qemu-devel

Split stimer_expiration() into two parts - timer expiration message
sending and timer restart/cleanup based on timer state(config).

This also fixes a bug where a one-shot timer message whose delivery
failed once would get lost for good.

Signed-off-by: Andrey Smetanin <asmetanin@virtuozzo.com>
Reviewed-by: Roman Kagan <rkagan@virtuozzo.com>
CC: Gleb Natapov <gleb@kernel.org>
CC: Paolo Bonzini <pbonzini@redhat.com>
CC: Roman Kagan <rkagan@virtuozzo.com>
CC: Denis V. Lunev <den@openvz.org>
CC: qemu-devel@nongnu.org
---
 arch/x86/kvm/hyperv.c | 26 ++++++++++++++------------
 1 file changed, 14 insertions(+), 12 deletions(-)

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index 0dd7d17..5f85c12 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -554,30 +554,27 @@ static int synic_deliver_msg(struct kvm_vcpu_hv_synic *synic, u32 sint,
 	return r;
 }
 
-static void stimer_send_msg(struct kvm_vcpu_hv_stimer *stimer)
+static int stimer_send_msg(struct kvm_vcpu_hv_stimer *stimer)
 {
 	struct kvm_vcpu *vcpu = stimer_to_vcpu(stimer);
 	struct hv_message *msg = &stimer->msg;
 	struct hv_timer_message_payload *payload =
 			(struct hv_timer_message_payload *)&msg->u.payload;
-	int r;
 
-	stimer->msg_pending = true;
 	payload->expiration_time = stimer->exp_time;
 	payload->delivery_time = get_time_ref_counter(vcpu->kvm);
-	r = synic_deliver_msg(vcpu_to_synic(vcpu),
-			      HV_STIMER_SINT(stimer->config), msg);
-	if (!r)
-		stimer->msg_pending = false;
+	return synic_deliver_msg(vcpu_to_synic(vcpu),
+				 HV_STIMER_SINT(stimer->config), msg);
 }
 
 static void stimer_expiration(struct kvm_vcpu_hv_stimer *stimer)
 {
-	stimer_send_msg(stimer);
-	if (!(stimer->config & HV_STIMER_PERIODIC))
-		stimer->config &= ~HV_STIMER_ENABLE;
-	else
-		stimer_start(stimer);
+	stimer->msg_pending = true;
+	if (!stimer_send_msg(stimer)) {
+		stimer->msg_pending = false;
+		if (!(stimer->config & HV_STIMER_PERIODIC))
+			stimer->config &= ~HV_STIMER_ENABLE;
+	}
 }
 
 void kvm_hv_process_stimers(struct kvm_vcpu *vcpu)
@@ -594,6 +591,11 @@ void kvm_hv_process_stimers(struct kvm_vcpu *vcpu)
 				time_now = get_time_ref_counter(vcpu->kvm);
 				if (time_now >= stimer->exp_time)
 					stimer_expiration(stimer);
+
+				if (stimer->config & HV_STIMER_ENABLE)
+					stimer_start(stimer);
+				else
+					stimer_cleanup(stimer);
 			}
 		}
 }
-- 
2.4.3


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

* [Qemu-devel] [PATCH v2 4/7] kvm/x86: Reorg stimer_expiration() to better control timer restart
@ 2015-12-28 15:27   ` Andrey Smetanin
  0 siblings, 0 replies; 22+ messages in thread
From: Andrey Smetanin @ 2015-12-28 15:27 UTC (permalink / raw)
  To: kvm; +Cc: Gleb Natapov, Paolo Bonzini, qemu-devel, Roman Kagan, Denis V. Lunev

Split stimer_expiration() into two parts - timer expiration message
sending and timer restart/cleanup based on timer state(config).

This also fixes a bug where a one-shot timer message whose delivery
failed once would get lost for good.

Signed-off-by: Andrey Smetanin <asmetanin@virtuozzo.com>
Reviewed-by: Roman Kagan <rkagan@virtuozzo.com>
CC: Gleb Natapov <gleb@kernel.org>
CC: Paolo Bonzini <pbonzini@redhat.com>
CC: Roman Kagan <rkagan@virtuozzo.com>
CC: Denis V. Lunev <den@openvz.org>
CC: qemu-devel@nongnu.org
---
 arch/x86/kvm/hyperv.c | 26 ++++++++++++++------------
 1 file changed, 14 insertions(+), 12 deletions(-)

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index 0dd7d17..5f85c12 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -554,30 +554,27 @@ static int synic_deliver_msg(struct kvm_vcpu_hv_synic *synic, u32 sint,
 	return r;
 }
 
-static void stimer_send_msg(struct kvm_vcpu_hv_stimer *stimer)
+static int stimer_send_msg(struct kvm_vcpu_hv_stimer *stimer)
 {
 	struct kvm_vcpu *vcpu = stimer_to_vcpu(stimer);
 	struct hv_message *msg = &stimer->msg;
 	struct hv_timer_message_payload *payload =
 			(struct hv_timer_message_payload *)&msg->u.payload;
-	int r;
 
-	stimer->msg_pending = true;
 	payload->expiration_time = stimer->exp_time;
 	payload->delivery_time = get_time_ref_counter(vcpu->kvm);
-	r = synic_deliver_msg(vcpu_to_synic(vcpu),
-			      HV_STIMER_SINT(stimer->config), msg);
-	if (!r)
-		stimer->msg_pending = false;
+	return synic_deliver_msg(vcpu_to_synic(vcpu),
+				 HV_STIMER_SINT(stimer->config), msg);
 }
 
 static void stimer_expiration(struct kvm_vcpu_hv_stimer *stimer)
 {
-	stimer_send_msg(stimer);
-	if (!(stimer->config & HV_STIMER_PERIODIC))
-		stimer->config &= ~HV_STIMER_ENABLE;
-	else
-		stimer_start(stimer);
+	stimer->msg_pending = true;
+	if (!stimer_send_msg(stimer)) {
+		stimer->msg_pending = false;
+		if (!(stimer->config & HV_STIMER_PERIODIC))
+			stimer->config &= ~HV_STIMER_ENABLE;
+	}
 }
 
 void kvm_hv_process_stimers(struct kvm_vcpu *vcpu)
@@ -594,6 +591,11 @@ void kvm_hv_process_stimers(struct kvm_vcpu *vcpu)
 				time_now = get_time_ref_counter(vcpu->kvm);
 				if (time_now >= stimer->exp_time)
 					stimer_expiration(stimer);
+
+				if (stimer->config & HV_STIMER_ENABLE)
+					stimer_start(stimer);
+				else
+					stimer_cleanup(stimer);
 			}
 		}
 }
-- 
2.4.3

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

* [PATCH v2 5/7] kvm/x86: Hyper-V fix SynIC timer disabling condition
  2015-12-28 15:27 ` [Qemu-devel] " Andrey Smetanin
@ 2015-12-28 15:27   ` Andrey Smetanin
  -1 siblings, 0 replies; 22+ messages in thread
From: Andrey Smetanin @ 2015-12-28 15:27 UTC (permalink / raw)
  To: kvm; +Cc: Gleb Natapov, Paolo Bonzini, Roman Kagan, Denis V. Lunev, qemu-devel

Hypervisor Function Specification(HFS) doesn't require
to disable SynIC timer at timer config write if timer->count = 0.

So drop this check, this allow to load timers MSR's
during migration restore, because config are set before count
in QEMU side.

Also fix condition according to HFS doc(15.3.1):
"It is not permitted to set the SINTx field to zero for an
enabled timer. If attempted, the timer will be
marked disabled (that is, bit 0 cleared) immediately."

Signed-off-by: Andrey Smetanin <asmetanin@virtuozzo.com>
Reviewed-by: Roman Kagan <rkagan@virtuozzo.com>
CC: Gleb Natapov <gleb@kernel.org>
CC: Paolo Bonzini <pbonzini@redhat.com>
CC: Roman Kagan <rkagan@virtuozzo.com>
CC: Denis V. Lunev <den@openvz.org>
CC: qemu-devel@nongnu.org
---
 arch/x86/kvm/hyperv.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index 5f85c12..abfb920 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -474,7 +474,7 @@ static int stimer_start(struct kvm_vcpu_hv_stimer *stimer)
 static int stimer_set_config(struct kvm_vcpu_hv_stimer *stimer, u64 config,
 			     bool host)
 {
-	if (stimer->count == 0 || HV_STIMER_SINT(config) == 0)
+	if ((stimer->config & HV_STIMER_ENABLE) && HV_STIMER_SINT(config) == 0)
 		config &= ~HV_STIMER_ENABLE;
 	stimer->config = config;
 	stimer_cleanup(stimer);
-- 
2.4.3


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

* [Qemu-devel] [PATCH v2 5/7] kvm/x86: Hyper-V fix SynIC timer disabling condition
@ 2015-12-28 15:27   ` Andrey Smetanin
  0 siblings, 0 replies; 22+ messages in thread
From: Andrey Smetanin @ 2015-12-28 15:27 UTC (permalink / raw)
  To: kvm; +Cc: Gleb Natapov, Paolo Bonzini, qemu-devel, Roman Kagan, Denis V. Lunev

Hypervisor Function Specification(HFS) doesn't require
to disable SynIC timer at timer config write if timer->count = 0.

So drop this check, this allow to load timers MSR's
during migration restore, because config are set before count
in QEMU side.

Also fix condition according to HFS doc(15.3.1):
"It is not permitted to set the SINTx field to zero for an
enabled timer. If attempted, the timer will be
marked disabled (that is, bit 0 cleared) immediately."

Signed-off-by: Andrey Smetanin <asmetanin@virtuozzo.com>
Reviewed-by: Roman Kagan <rkagan@virtuozzo.com>
CC: Gleb Natapov <gleb@kernel.org>
CC: Paolo Bonzini <pbonzini@redhat.com>
CC: Roman Kagan <rkagan@virtuozzo.com>
CC: Denis V. Lunev <den@openvz.org>
CC: qemu-devel@nongnu.org
---
 arch/x86/kvm/hyperv.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index 5f85c12..abfb920 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -474,7 +474,7 @@ static int stimer_start(struct kvm_vcpu_hv_stimer *stimer)
 static int stimer_set_config(struct kvm_vcpu_hv_stimer *stimer, u64 config,
 			     bool host)
 {
-	if (stimer->count == 0 || HV_STIMER_SINT(config) == 0)
+	if ((stimer->config & HV_STIMER_ENABLE) && HV_STIMER_SINT(config) == 0)
 		config &= ~HV_STIMER_ENABLE;
 	stimer->config = config;
 	stimer_cleanup(stimer);
-- 
2.4.3

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

* [PATCH v2 6/7] kvm/x86: Skip SynIC vector check for QEMU side
  2015-12-28 15:27 ` [Qemu-devel] " Andrey Smetanin
@ 2015-12-28 15:27   ` Andrey Smetanin
  -1 siblings, 0 replies; 22+ messages in thread
From: Andrey Smetanin @ 2015-12-28 15:27 UTC (permalink / raw)
  To: kvm; +Cc: Gleb Natapov, Paolo Bonzini, Roman Kagan, Denis V. Lunev, qemu-devel

QEMU zero-inits Hyper-V SynIC vectors. We should allow that,
and don't reject zero values if set by the host.

Signed-off-by: Andrey Smetanin <asmetanin@virtuozzo.com>
Reviewed-by: Roman Kagan <rkagan@virtuozzo.com>
CC: Gleb Natapov <gleb@kernel.org>
CC: Paolo Bonzini <pbonzini@redhat.com>
CC: Roman Kagan <rkagan@virtuozzo.com>
CC: Denis V. Lunev <den@openvz.org>
CC: qemu-devel@nongnu.org
---
 arch/x86/kvm/hyperv.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index abfb920..ddae13e 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -72,12 +72,13 @@ static bool synic_has_vector_auto_eoi(struct kvm_vcpu_hv_synic *synic,
 	return false;
 }
 
-static int synic_set_sint(struct kvm_vcpu_hv_synic *synic, int sint, u64 data)
+static int synic_set_sint(struct kvm_vcpu_hv_synic *synic, int sint,
+			  u64 data, bool host)
 {
 	int vector;
 
 	vector = data & HV_SYNIC_SINT_VECTOR_MASK;
-	if (vector < 16)
+	if (vector < 16 && !host)
 		return 1;
 	/*
 	 * Guest may configure multiple SINTs to use the same vector, so
@@ -247,7 +248,7 @@ static int synic_set_msr(struct kvm_vcpu_hv_synic *synic,
 		break;
 	}
 	case HV_X64_MSR_SINT0 ... HV_X64_MSR_SINT15:
-		ret = synic_set_sint(synic, msr - HV_X64_MSR_SINT0, data);
+		ret = synic_set_sint(synic, msr - HV_X64_MSR_SINT0, data, host);
 		break;
 	default:
 		ret = 1;
-- 
2.4.3


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

* [Qemu-devel] [PATCH v2 6/7] kvm/x86: Skip SynIC vector check for QEMU side
@ 2015-12-28 15:27   ` Andrey Smetanin
  0 siblings, 0 replies; 22+ messages in thread
From: Andrey Smetanin @ 2015-12-28 15:27 UTC (permalink / raw)
  To: kvm; +Cc: Gleb Natapov, Paolo Bonzini, qemu-devel, Roman Kagan, Denis V. Lunev

QEMU zero-inits Hyper-V SynIC vectors. We should allow that,
and don't reject zero values if set by the host.

Signed-off-by: Andrey Smetanin <asmetanin@virtuozzo.com>
Reviewed-by: Roman Kagan <rkagan@virtuozzo.com>
CC: Gleb Natapov <gleb@kernel.org>
CC: Paolo Bonzini <pbonzini@redhat.com>
CC: Roman Kagan <rkagan@virtuozzo.com>
CC: Denis V. Lunev <den@openvz.org>
CC: qemu-devel@nongnu.org
---
 arch/x86/kvm/hyperv.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index abfb920..ddae13e 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -72,12 +72,13 @@ static bool synic_has_vector_auto_eoi(struct kvm_vcpu_hv_synic *synic,
 	return false;
 }
 
-static int synic_set_sint(struct kvm_vcpu_hv_synic *synic, int sint, u64 data)
+static int synic_set_sint(struct kvm_vcpu_hv_synic *synic, int sint,
+			  u64 data, bool host)
 {
 	int vector;
 
 	vector = data & HV_SYNIC_SINT_VECTOR_MASK;
-	if (vector < 16)
+	if (vector < 16 && !host)
 		return 1;
 	/*
 	 * Guest may configure multiple SINTs to use the same vector, so
@@ -247,7 +248,7 @@ static int synic_set_msr(struct kvm_vcpu_hv_synic *synic,
 		break;
 	}
 	case HV_X64_MSR_SINT0 ... HV_X64_MSR_SINT15:
-		ret = synic_set_sint(synic, msr - HV_X64_MSR_SINT0, data);
+		ret = synic_set_sint(synic, msr - HV_X64_MSR_SINT0, data, host);
 		break;
 	default:
 		ret = 1;
-- 
2.4.3

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

* [PATCH v2 7/7] kvm/x86: Update SynIC timers on guest entry only
  2015-12-28 15:27 ` [Qemu-devel] " Andrey Smetanin
@ 2015-12-28 15:27   ` Andrey Smetanin
  -1 siblings, 0 replies; 22+ messages in thread
From: Andrey Smetanin @ 2015-12-28 15:27 UTC (permalink / raw)
  To: kvm; +Cc: Gleb Natapov, Paolo Bonzini, qemu-devel, Roman Kagan, Denis V. Lunev

Consolidate updating the Hyper-V SynIC timers in a
single place: on guest entry in processing KVM_REQ_HV_STIMER
request.  This simplifies the overall logic, and makes sure
the most current state of msrs and guest clock is used for
arming the timers (to achieve that, KVM_REQ_HV_STIMER
has to be processed after KVM_REQ_CLOCK_UPDATE).

Signed-off-by: Andrey Smetanin <asmetanin@virtuozzo.com>
Reviewed-by: Roman Kagan <rkagan@virtuozzo.com>
CC: Gleb Natapov <gleb@kernel.org>
CC: Paolo Bonzini <pbonzini@redhat.com>
CC: Roman Kagan <rkagan@virtuozzo.com>
CC: Denis V. Lunev <den@openvz.org>
CC: qemu-devel@nongnu.org
---
 arch/x86/kvm/hyperv.c | 38 +++++++++++++++++++-------------------
 arch/x86/kvm/x86.c    |  6 ++++++
 2 files changed, 25 insertions(+), 19 deletions(-)

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index ddae13e..101c2e4 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -389,7 +389,7 @@ static u64 get_time_ref_counter(struct kvm *kvm)
 	return div_u64(get_kernel_ns() + kvm->arch.kvmclock_offset, 100);
 }
 
-static void stimer_mark_expired(struct kvm_vcpu_hv_stimer *stimer,
+static void stimer_mark_pending(struct kvm_vcpu_hv_stimer *stimer,
 				bool vcpu_kick)
 {
 	struct kvm_vcpu *vcpu = stimer_to_vcpu(stimer);
@@ -417,7 +417,7 @@ static enum hrtimer_restart stimer_timer_callback(struct hrtimer *timer)
 	struct kvm_vcpu_hv_stimer *stimer;
 
 	stimer = container_of(timer, struct kvm_vcpu_hv_stimer, timer);
-	stimer_mark_expired(stimer, true);
+	stimer_mark_pending(stimer, true);
 
 	return HRTIMER_NORESTART;
 }
@@ -462,7 +462,7 @@ static int stimer_start(struct kvm_vcpu_hv_stimer *stimer)
 		 * "If a one shot is enabled and the specified count is in
 		 * the past, it will expire immediately."
 		 */
-		stimer_mark_expired(stimer, false);
+		stimer_mark_pending(stimer, false);
 		return 0;
 	}
 
@@ -475,30 +475,24 @@ static int stimer_start(struct kvm_vcpu_hv_stimer *stimer)
 static int stimer_set_config(struct kvm_vcpu_hv_stimer *stimer, u64 config,
 			     bool host)
 {
+	stimer_cleanup(stimer);
 	if ((stimer->config & HV_STIMER_ENABLE) && HV_STIMER_SINT(config) == 0)
 		config &= ~HV_STIMER_ENABLE;
 	stimer->config = config;
-	stimer_cleanup(stimer);
-	if (stimer->config & HV_STIMER_ENABLE)
-		if (stimer_start(stimer))
-			return 1;
+	stimer_mark_pending(stimer, false);
 	return 0;
 }
 
 static int stimer_set_count(struct kvm_vcpu_hv_stimer *stimer, u64 count,
 			    bool host)
 {
-	stimer->count = count;
-
 	stimer_cleanup(stimer);
+	stimer->count = count;
 	if (stimer->count == 0)
 		stimer->config &= ~HV_STIMER_ENABLE;
-	else if (stimer->config & HV_STIMER_AUTOENABLE) {
+	else if (stimer->config & HV_STIMER_AUTOENABLE)
 		stimer->config |= HV_STIMER_ENABLE;
-		if (stimer_start(stimer))
-			return 1;
-	}
-
+	stimer_mark_pending(stimer, false);
 	return 0;
 }
 
@@ -582,18 +576,24 @@ void kvm_hv_process_stimers(struct kvm_vcpu *vcpu)
 {
 	struct kvm_vcpu_hv *hv_vcpu = vcpu_to_hv_vcpu(vcpu);
 	struct kvm_vcpu_hv_stimer *stimer;
-	u64 time_now;
+	u64 time_now, exp_time;
 	int i;
 
 	for (i = 0; i < ARRAY_SIZE(hv_vcpu->stimer); i++)
 		if (test_and_clear_bit(i, hv_vcpu->stimer_pending_bitmap)) {
 			stimer = &hv_vcpu->stimer[i];
 			if (stimer->config & HV_STIMER_ENABLE) {
-				time_now = get_time_ref_counter(vcpu->kvm);
-				if (time_now >= stimer->exp_time)
-					stimer_expiration(stimer);
+				exp_time = stimer->exp_time;
+
+				if (exp_time) {
+					time_now =
+						get_time_ref_counter(vcpu->kvm);
+					if (time_now >= exp_time)
+						stimer_expiration(stimer);
+				}
 
-				if (stimer->config & HV_STIMER_ENABLE)
+				if ((stimer->config & HV_STIMER_ENABLE) &&
+				    stimer->count)
 					stimer_start(stimer);
 				else
 					stimer_cleanup(stimer);
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index e23137d..9610516 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -6491,6 +6491,12 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
 			r = 0;
 			goto out;
 		}
+
+		/*
+		 * KVM_REQ_HV_STIMER has to be processed after
+		 * KVM_REQ_CLOCK_UPDATE, because Hyper-V SynIC timers
+		 * depend on the guest clock being up-to-date
+		 */
 		if (kvm_check_request(KVM_REQ_HV_STIMER, vcpu))
 			kvm_hv_process_stimers(vcpu);
 	}
-- 
2.4.3

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

* [Qemu-devel] [PATCH v2 7/7] kvm/x86: Update SynIC timers on guest entry only
@ 2015-12-28 15:27   ` Andrey Smetanin
  0 siblings, 0 replies; 22+ messages in thread
From: Andrey Smetanin @ 2015-12-28 15:27 UTC (permalink / raw)
  To: kvm; +Cc: Gleb Natapov, Paolo Bonzini, qemu-devel, Roman Kagan, Denis V. Lunev

Consolidate updating the Hyper-V SynIC timers in a
single place: on guest entry in processing KVM_REQ_HV_STIMER
request.  This simplifies the overall logic, and makes sure
the most current state of msrs and guest clock is used for
arming the timers (to achieve that, KVM_REQ_HV_STIMER
has to be processed after KVM_REQ_CLOCK_UPDATE).

Signed-off-by: Andrey Smetanin <asmetanin@virtuozzo.com>
Reviewed-by: Roman Kagan <rkagan@virtuozzo.com>
CC: Gleb Natapov <gleb@kernel.org>
CC: Paolo Bonzini <pbonzini@redhat.com>
CC: Roman Kagan <rkagan@virtuozzo.com>
CC: Denis V. Lunev <den@openvz.org>
CC: qemu-devel@nongnu.org
---
 arch/x86/kvm/hyperv.c | 38 +++++++++++++++++++-------------------
 arch/x86/kvm/x86.c    |  6 ++++++
 2 files changed, 25 insertions(+), 19 deletions(-)

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index ddae13e..101c2e4 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -389,7 +389,7 @@ static u64 get_time_ref_counter(struct kvm *kvm)
 	return div_u64(get_kernel_ns() + kvm->arch.kvmclock_offset, 100);
 }
 
-static void stimer_mark_expired(struct kvm_vcpu_hv_stimer *stimer,
+static void stimer_mark_pending(struct kvm_vcpu_hv_stimer *stimer,
 				bool vcpu_kick)
 {
 	struct kvm_vcpu *vcpu = stimer_to_vcpu(stimer);
@@ -417,7 +417,7 @@ static enum hrtimer_restart stimer_timer_callback(struct hrtimer *timer)
 	struct kvm_vcpu_hv_stimer *stimer;
 
 	stimer = container_of(timer, struct kvm_vcpu_hv_stimer, timer);
-	stimer_mark_expired(stimer, true);
+	stimer_mark_pending(stimer, true);
 
 	return HRTIMER_NORESTART;
 }
@@ -462,7 +462,7 @@ static int stimer_start(struct kvm_vcpu_hv_stimer *stimer)
 		 * "If a one shot is enabled and the specified count is in
 		 * the past, it will expire immediately."
 		 */
-		stimer_mark_expired(stimer, false);
+		stimer_mark_pending(stimer, false);
 		return 0;
 	}
 
@@ -475,30 +475,24 @@ static int stimer_start(struct kvm_vcpu_hv_stimer *stimer)
 static int stimer_set_config(struct kvm_vcpu_hv_stimer *stimer, u64 config,
 			     bool host)
 {
+	stimer_cleanup(stimer);
 	if ((stimer->config & HV_STIMER_ENABLE) && HV_STIMER_SINT(config) == 0)
 		config &= ~HV_STIMER_ENABLE;
 	stimer->config = config;
-	stimer_cleanup(stimer);
-	if (stimer->config & HV_STIMER_ENABLE)
-		if (stimer_start(stimer))
-			return 1;
+	stimer_mark_pending(stimer, false);
 	return 0;
 }
 
 static int stimer_set_count(struct kvm_vcpu_hv_stimer *stimer, u64 count,
 			    bool host)
 {
-	stimer->count = count;
-
 	stimer_cleanup(stimer);
+	stimer->count = count;
 	if (stimer->count == 0)
 		stimer->config &= ~HV_STIMER_ENABLE;
-	else if (stimer->config & HV_STIMER_AUTOENABLE) {
+	else if (stimer->config & HV_STIMER_AUTOENABLE)
 		stimer->config |= HV_STIMER_ENABLE;
-		if (stimer_start(stimer))
-			return 1;
-	}
-
+	stimer_mark_pending(stimer, false);
 	return 0;
 }
 
@@ -582,18 +576,24 @@ void kvm_hv_process_stimers(struct kvm_vcpu *vcpu)
 {
 	struct kvm_vcpu_hv *hv_vcpu = vcpu_to_hv_vcpu(vcpu);
 	struct kvm_vcpu_hv_stimer *stimer;
-	u64 time_now;
+	u64 time_now, exp_time;
 	int i;
 
 	for (i = 0; i < ARRAY_SIZE(hv_vcpu->stimer); i++)
 		if (test_and_clear_bit(i, hv_vcpu->stimer_pending_bitmap)) {
 			stimer = &hv_vcpu->stimer[i];
 			if (stimer->config & HV_STIMER_ENABLE) {
-				time_now = get_time_ref_counter(vcpu->kvm);
-				if (time_now >= stimer->exp_time)
-					stimer_expiration(stimer);
+				exp_time = stimer->exp_time;
+
+				if (exp_time) {
+					time_now =
+						get_time_ref_counter(vcpu->kvm);
+					if (time_now >= exp_time)
+						stimer_expiration(stimer);
+				}
 
-				if (stimer->config & HV_STIMER_ENABLE)
+				if ((stimer->config & HV_STIMER_ENABLE) &&
+				    stimer->count)
 					stimer_start(stimer);
 				else
 					stimer_cleanup(stimer);
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index e23137d..9610516 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -6491,6 +6491,12 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
 			r = 0;
 			goto out;
 		}
+
+		/*
+		 * KVM_REQ_HV_STIMER has to be processed after
+		 * KVM_REQ_CLOCK_UPDATE, because Hyper-V SynIC timers
+		 * depend on the guest clock being up-to-date
+		 */
 		if (kvm_check_request(KVM_REQ_HV_STIMER, vcpu))
 			kvm_hv_process_stimers(vcpu);
 	}
-- 
2.4.3

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

* Re: [PATCH v2 3/7] kvm/x86: Hyper-V unify stimer_start() and stimer_restart()
  2015-12-28 15:27   ` [Qemu-devel] " Andrey Smetanin
@ 2016-01-07 16:40     ` Paolo Bonzini
  -1 siblings, 0 replies; 22+ messages in thread
From: Paolo Bonzini @ 2016-01-07 16:40 UTC (permalink / raw)
  To: Andrey Smetanin, kvm
  Cc: Gleb Natapov, Roman Kagan, Denis V. Lunev, qemu-devel



On 28/12/2015 16:27, Andrey Smetanin wrote:
> This will be used in future to start Hyper-V SynIC timer
> in several places by one logic in one function.
> 
> Changes v2:
> * drop stimer->count == 0 check inside stimer_start()
> * comment stimer_start() assumptions

Can you replace comments with WARN_ON_ONCE?

Paolo

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

* Re: [Qemu-devel] [PATCH v2 3/7] kvm/x86: Hyper-V unify stimer_start() and stimer_restart()
@ 2016-01-07 16:40     ` Paolo Bonzini
  0 siblings, 0 replies; 22+ messages in thread
From: Paolo Bonzini @ 2016-01-07 16:40 UTC (permalink / raw)
  To: Andrey Smetanin, kvm
  Cc: Gleb Natapov, Denis V. Lunev, Roman Kagan, qemu-devel



On 28/12/2015 16:27, Andrey Smetanin wrote:
> This will be used in future to start Hyper-V SynIC timer
> in several places by one logic in one function.
> 
> Changes v2:
> * drop stimer->count == 0 check inside stimer_start()
> * comment stimer_start() assumptions

Can you replace comments with WARN_ON_ONCE?

Paolo

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

* Re: [PATCH v2 0/7] KVM: Hyper-V SynIC timers migration fixes
  2015-12-28 15:27 ` [Qemu-devel] " Andrey Smetanin
@ 2016-01-07 16:42   ` Paolo Bonzini
  -1 siblings, 0 replies; 22+ messages in thread
From: Paolo Bonzini @ 2016-01-07 16:42 UTC (permalink / raw)
  To: Andrey Smetanin, kvm
  Cc: Gleb Natapov, Roman Kagan, Denis V. Lunev, qemu-devel



On 28/12/2015 16:27, Andrey Smetanin wrote:
> During testing of Windows 2012R2 guest migration with
> Hyper-V SynIC timers enabled we found several bugs
> which lead to restoring guest in a hung state.
> 
> This patch series provides several fixes to make the
> migration of guest with Hyper-V SynIC timers enabled
> succeed.
> 
> The series applies on top of
> 'kvm/x86: Remove Hyper-V SynIC timer stopping'
> previously sent.
> 
> Changes v2:
> * fix incorrect logical operation for one-shot timers
> * drop stimer->count == 0 inside stimer_start()
> * comment stimer_start() assumtions
> 
> Signed-off-by: Andrey Smetanin <asmetanin@virtuozzo.com>
> Reviewed-by: Roman Kagan <rkagan@virtuozzo.com>
> CC: Gleb Natapov <gleb@kernel.org>
> CC: Paolo Bonzini <pbonzini@redhat.com>
> CC: Roman Kagan <rkagan@virtuozzo.com>
> CC: Denis V. Lunev <den@openvz.org>
> CC: qemu-devel@nongnu.org
> 
> Andrey Smetanin (7):
>   kvm/x86: Hyper-V timers fix incorrect logical operation
>   kvm/x86: Drop stimer_stop() function
>   kvm/x86: Hyper-V unify stimer_start() and stimer_restart()
>   kvm/x86: Reorg stimer_expiration() to better control timer restart
>   kvm/x86: Hyper-V fix SynIC timer disabling condition
>   kvm/x86: Skip SynIC vector check for QEMU side
>   kvm/x86: Update SynIC timers on guest entry only
> 
>  arch/x86/kvm/hyperv.c | 119 ++++++++++++++++++++++++--------------------------
>  arch/x86/kvm/x86.c    |   6 +++
>  2 files changed, 63 insertions(+), 62 deletions(-)
> 


Applied this instead of v1. :)

Paolo

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

* Re: [Qemu-devel] [PATCH v2 0/7] KVM: Hyper-V SynIC timers migration fixes
@ 2016-01-07 16:42   ` Paolo Bonzini
  0 siblings, 0 replies; 22+ messages in thread
From: Paolo Bonzini @ 2016-01-07 16:42 UTC (permalink / raw)
  To: Andrey Smetanin, kvm
  Cc: Gleb Natapov, Denis V. Lunev, Roman Kagan, qemu-devel



On 28/12/2015 16:27, Andrey Smetanin wrote:
> During testing of Windows 2012R2 guest migration with
> Hyper-V SynIC timers enabled we found several bugs
> which lead to restoring guest in a hung state.
> 
> This patch series provides several fixes to make the
> migration of guest with Hyper-V SynIC timers enabled
> succeed.
> 
> The series applies on top of
> 'kvm/x86: Remove Hyper-V SynIC timer stopping'
> previously sent.
> 
> Changes v2:
> * fix incorrect logical operation for one-shot timers
> * drop stimer->count == 0 inside stimer_start()
> * comment stimer_start() assumtions
> 
> Signed-off-by: Andrey Smetanin <asmetanin@virtuozzo.com>
> Reviewed-by: Roman Kagan <rkagan@virtuozzo.com>
> CC: Gleb Natapov <gleb@kernel.org>
> CC: Paolo Bonzini <pbonzini@redhat.com>
> CC: Roman Kagan <rkagan@virtuozzo.com>
> CC: Denis V. Lunev <den@openvz.org>
> CC: qemu-devel@nongnu.org
> 
> Andrey Smetanin (7):
>   kvm/x86: Hyper-V timers fix incorrect logical operation
>   kvm/x86: Drop stimer_stop() function
>   kvm/x86: Hyper-V unify stimer_start() and stimer_restart()
>   kvm/x86: Reorg stimer_expiration() to better control timer restart
>   kvm/x86: Hyper-V fix SynIC timer disabling condition
>   kvm/x86: Skip SynIC vector check for QEMU side
>   kvm/x86: Update SynIC timers on guest entry only
> 
>  arch/x86/kvm/hyperv.c | 119 ++++++++++++++++++++++++--------------------------
>  arch/x86/kvm/x86.c    |   6 +++
>  2 files changed, 63 insertions(+), 62 deletions(-)
> 


Applied this instead of v1. :)

Paolo

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

* Re: [PATCH v2 3/7] kvm/x86: Hyper-V unify stimer_start() and stimer_restart()
  2016-01-07 16:40     ` [Qemu-devel] " Paolo Bonzini
@ 2016-01-07 20:15       ` Andrey Smetanin
  -1 siblings, 0 replies; 22+ messages in thread
From: Andrey Smetanin @ 2016-01-07 20:15 UTC (permalink / raw)
  To: Paolo Bonzini, kvm; +Cc: Gleb Natapov, Roman Kagan, Denis V. Lunev, qemu-devel



On 01/07/2016 07:40 PM, Paolo Bonzini wrote:
>
>
> On 28/12/2015 16:27, Andrey Smetanin wrote:
>> This will be used in future to start Hyper-V SynIC timer
>> in several places by one logic in one function.
>>
>> Changes v2:
>> * drop stimer->count == 0 check inside stimer_start()
>> * comment stimer_start() assumptions
>
> Can you replace comments with WARN_ON_ONCE?
Yes, I can, ETA 12 Jan since i'm on vacation.
>
> Paolo
>

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

* Re: [Qemu-devel] [PATCH v2 3/7] kvm/x86: Hyper-V unify stimer_start() and stimer_restart()
@ 2016-01-07 20:15       ` Andrey Smetanin
  0 siblings, 0 replies; 22+ messages in thread
From: Andrey Smetanin @ 2016-01-07 20:15 UTC (permalink / raw)
  To: Paolo Bonzini, kvm; +Cc: Gleb Natapov, Denis V. Lunev, Roman Kagan, qemu-devel



On 01/07/2016 07:40 PM, Paolo Bonzini wrote:
>
>
> On 28/12/2015 16:27, Andrey Smetanin wrote:
>> This will be used in future to start Hyper-V SynIC timer
>> in several places by one logic in one function.
>>
>> Changes v2:
>> * drop stimer->count == 0 check inside stimer_start()
>> * comment stimer_start() assumptions
>
> Can you replace comments with WARN_ON_ONCE?
Yes, I can, ETA 12 Jan since i'm on vacation.
>
> Paolo
>

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

end of thread, other threads:[~2016-01-07 20:16 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-12-28 15:27 [PATCH v2 0/7] KVM: Hyper-V SynIC timers migration fixes Andrey Smetanin
2015-12-28 15:27 ` [Qemu-devel] " Andrey Smetanin
2015-12-28 15:27 ` [PATCH v2 1/7] kvm/x86: Hyper-V timers fix incorrect logical operation Andrey Smetanin
2015-12-28 15:27   ` [Qemu-devel] " Andrey Smetanin
2015-12-28 15:27 ` [PATCH v2 2/7] kvm/x86: Drop stimer_stop() function Andrey Smetanin
2015-12-28 15:27   ` [Qemu-devel] " Andrey Smetanin
2015-12-28 15:27 ` [PATCH v2 3/7] kvm/x86: Hyper-V unify stimer_start() and stimer_restart() Andrey Smetanin
2015-12-28 15:27   ` [Qemu-devel] " Andrey Smetanin
2016-01-07 16:40   ` Paolo Bonzini
2016-01-07 16:40     ` [Qemu-devel] " Paolo Bonzini
2016-01-07 20:15     ` Andrey Smetanin
2016-01-07 20:15       ` [Qemu-devel] " Andrey Smetanin
2015-12-28 15:27 ` [PATCH v2 4/7] kvm/x86: Reorg stimer_expiration() to better control timer restart Andrey Smetanin
2015-12-28 15:27   ` [Qemu-devel] " Andrey Smetanin
2015-12-28 15:27 ` [PATCH v2 5/7] kvm/x86: Hyper-V fix SynIC timer disabling condition Andrey Smetanin
2015-12-28 15:27   ` [Qemu-devel] " Andrey Smetanin
2015-12-28 15:27 ` [PATCH v2 6/7] kvm/x86: Skip SynIC vector check for QEMU side Andrey Smetanin
2015-12-28 15:27   ` [Qemu-devel] " Andrey Smetanin
2015-12-28 15:27 ` [PATCH v2 7/7] kvm/x86: Update SynIC timers on guest entry only Andrey Smetanin
2015-12-28 15:27   ` [Qemu-devel] " Andrey Smetanin
2016-01-07 16:42 ` [PATCH v2 0/7] KVM: Hyper-V SynIC timers migration fixes Paolo Bonzini
2016-01-07 16:42   ` [Qemu-devel] " Paolo Bonzini

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.