All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/9] KVM: Hyper-V SynIC timers
@ 2015-11-30 16:22 ` Andrey Smetanin
  0 siblings, 0 replies; 34+ messages in thread
From: Andrey Smetanin @ 2015-11-30 16:22 UTC (permalink / raw)
  To: kvm
  Cc: Gleb Natapov, Haiyang Zhang, qemu-devel, Roman Kagan,
	Denis V. Lunev, Paolo Bonzini, Vitaly Kuznetsov,
	K. Y. Srinivasan

Per Hyper-V specification (and as required by Hyper-V-aware guests),
SynIC provides 4 per-vCPU timers.  Each timer is programmed via a pair
of MSRs, and signals expiration by delivering a special format message
to the configured SynIC message slot and triggering the corresponding
synthetic interrupt.

Note: as implemented by this patch, all periodic timers are "lazy"
(i.e. if the vCPU wasn't scheduled for more than the timer period the
timer events are lost), regardless of the corresponding configuration
MSR.  If deemed necessary, the "catch up" mode (the timer period is
shortened until the timer catches up) will be implemented later.

The Hyper-V SynIC timers support is required to load winhv.sys
inside Windows guest on which guest VMBus devices depends on.

This patches depends on Hyper-V SynIC patches previosly sent.

Changes v2:
* Hyper-V headers patches split and fixes
* Use remainder to calculate peridic timer expiration time

Signed-off-by: Andrey Smetanin <asmetanin@virtuozzo.com>
CC: Gleb Natapov <gleb@kernel.org>
CC: Paolo Bonzini <pbonzini@redhat.com>
CC: "K. Y. Srinivasan" <kys@microsoft.com>
CC: Haiyang Zhang <haiyangz@microsoft.com>
CC: Vitaly Kuznetsov <vkuznets@redhat.com>
CC: Roman Kagan <rkagan@virtuozzo.com>
CC: Denis V. Lunev <den@openvz.org>
CC: qemu-devel@nongnu.org

Andrey Smetanin (9):
  drivers/hv: Replace enum hv_message_type by u32
  drivers/hv: Move HV_SYNIC_STIMER_COUNT into Hyper-V UAPI x86 header
  drivers/hv: Move struct hv_message into UAPI Hyper-V x86 header
  drivers/hv: Move struct hv_timer_message_payload into UAPI Hyper-V x86
    header
  kvm/x86: Rearrange func's declarations inside Hyper-V header
  kvm/x86: Added Hyper-V vcpu_to_hv_vcpu()/hv_vcpu_to_vcpu() helpers
  kvm/x86: Hyper-V internal helper to read MSR HV_X64_MSR_TIME_REF_COUNT
  kvm/x86: Hyper-V SynIC message slot pending clearing at SINT ack
  kvm/x86: Hyper-V SynIC timers

 arch/x86/include/asm/kvm_host.h    |  13 ++
 arch/x86/include/uapi/asm/hyperv.h |  90 ++++++++++
 arch/x86/kvm/hyperv.c              | 360 ++++++++++++++++++++++++++++++++++++-
 arch/x86/kvm/hyperv.h              |  54 ++++--
 arch/x86/kvm/x86.c                 |   9 +
 drivers/hv/hv.c                    |   4 +-
 drivers/hv/hyperv_vmbus.h          |  92 +---------
 include/linux/kvm_host.h           |   3 +
 8 files changed, 516 insertions(+), 109 deletions(-)

-- 
2.4.3

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

* [Qemu-devel] [PATCH v2 0/9] KVM: Hyper-V SynIC timers
@ 2015-11-30 16:22 ` Andrey Smetanin
  0 siblings, 0 replies; 34+ messages in thread
From: Andrey Smetanin @ 2015-11-30 16:22 UTC (permalink / raw)
  To: kvm
  Cc: Gleb Natapov, Haiyang Zhang, qemu-devel, Roman Kagan,
	Denis V. Lunev, Paolo Bonzini, Vitaly Kuznetsov,
	K. Y. Srinivasan

Per Hyper-V specification (and as required by Hyper-V-aware guests),
SynIC provides 4 per-vCPU timers.  Each timer is programmed via a pair
of MSRs, and signals expiration by delivering a special format message
to the configured SynIC message slot and triggering the corresponding
synthetic interrupt.

Note: as implemented by this patch, all periodic timers are "lazy"
(i.e. if the vCPU wasn't scheduled for more than the timer period the
timer events are lost), regardless of the corresponding configuration
MSR.  If deemed necessary, the "catch up" mode (the timer period is
shortened until the timer catches up) will be implemented later.

The Hyper-V SynIC timers support is required to load winhv.sys
inside Windows guest on which guest VMBus devices depends on.

This patches depends on Hyper-V SynIC patches previosly sent.

Changes v2:
* Hyper-V headers patches split and fixes
* Use remainder to calculate peridic timer expiration time

Signed-off-by: Andrey Smetanin <asmetanin@virtuozzo.com>
CC: Gleb Natapov <gleb@kernel.org>
CC: Paolo Bonzini <pbonzini@redhat.com>
CC: "K. Y. Srinivasan" <kys@microsoft.com>
CC: Haiyang Zhang <haiyangz@microsoft.com>
CC: Vitaly Kuznetsov <vkuznets@redhat.com>
CC: Roman Kagan <rkagan@virtuozzo.com>
CC: Denis V. Lunev <den@openvz.org>
CC: qemu-devel@nongnu.org

Andrey Smetanin (9):
  drivers/hv: Replace enum hv_message_type by u32
  drivers/hv: Move HV_SYNIC_STIMER_COUNT into Hyper-V UAPI x86 header
  drivers/hv: Move struct hv_message into UAPI Hyper-V x86 header
  drivers/hv: Move struct hv_timer_message_payload into UAPI Hyper-V x86
    header
  kvm/x86: Rearrange func's declarations inside Hyper-V header
  kvm/x86: Added Hyper-V vcpu_to_hv_vcpu()/hv_vcpu_to_vcpu() helpers
  kvm/x86: Hyper-V internal helper to read MSR HV_X64_MSR_TIME_REF_COUNT
  kvm/x86: Hyper-V SynIC message slot pending clearing at SINT ack
  kvm/x86: Hyper-V SynIC timers

 arch/x86/include/asm/kvm_host.h    |  13 ++
 arch/x86/include/uapi/asm/hyperv.h |  90 ++++++++++
 arch/x86/kvm/hyperv.c              | 360 ++++++++++++++++++++++++++++++++++++-
 arch/x86/kvm/hyperv.h              |  54 ++++--
 arch/x86/kvm/x86.c                 |   9 +
 drivers/hv/hv.c                    |   4 +-
 drivers/hv/hyperv_vmbus.h          |  92 +---------
 include/linux/kvm_host.h           |   3 +
 8 files changed, 516 insertions(+), 109 deletions(-)

-- 
2.4.3

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

* [PATCH v2 1/9] drivers/hv: replace enum hv_message_type by u32
  2015-11-30 16:22 ` [Qemu-devel] " Andrey Smetanin
@ 2015-11-30 16:22   ` Andrey Smetanin
  -1 siblings, 0 replies; 34+ messages in thread
From: Andrey Smetanin @ 2015-11-30 16:22 UTC (permalink / raw)
  To: kvm
  Cc: Gleb Natapov, Haiyang Zhang, qemu-devel, Roman Kagan,
	Denis V. Lunev, Paolo Bonzini, Vitaly Kuznetsov,
	K. Y. Srinivasan

enum hv_message_type inside struct hv_message, hv_post_message
is not size portable. Replace enum by u32.

Signed-off-by: Andrey Smetanin <asmetanin@virtuozzo.com>
CC: Gleb Natapov <gleb@kernel.org>
CC: Paolo Bonzini <pbonzini@redhat.com>
CC: "K. Y. Srinivasan" <kys@microsoft.com>
CC: Haiyang Zhang <haiyangz@microsoft.com>
CC: Vitaly Kuznetsov <vkuznets@redhat.com>
CC: Roman Kagan <rkagan@virtuozzo.com>
CC: Denis V. Lunev <den@openvz.org>
CC: qemu-devel@nongnu.org

---
 drivers/hv/hv.c           |  4 ++--
 drivers/hv/hyperv_vmbus.h | 48 +++++++++++++++++++++++------------------------
 2 files changed, 25 insertions(+), 27 deletions(-)

diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
index 6341be8..dde7e1c 100644
--- a/drivers/hv/hv.c
+++ b/drivers/hv/hv.c
@@ -310,8 +310,8 @@ void hv_cleanup(void)
  * This involves a hypercall.
  */
 int hv_post_message(union hv_connection_id connection_id,
-		  enum hv_message_type message_type,
-		  void *payload, size_t payload_size)
+		    u32 message_type,
+		    void *payload, size_t payload_size)
 {
 
 	struct hv_input_post_message *aligned_msg;
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
index 3782636..e46e18c 100644
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -75,32 +75,30 @@ enum hv_cpuid_function {
 #define HV_EVENT_FLAGS_DWORD_COUNT	(256 / sizeof(u32))
 
 /* Define hypervisor message types. */
-enum hv_message_type {
-	HVMSG_NONE			= 0x00000000,
+#define HVMSG_NONE			0x00000000
 
-	/* Memory access messages. */
-	HVMSG_UNMAPPED_GPA		= 0x80000000,
-	HVMSG_GPA_INTERCEPT		= 0x80000001,
+/* Memory access messages. */
+#define HVMSG_UNMAPPED_GPA		0x80000000
+#define HVMSG_GPA_INTERCEPT		0x80000001
 
-	/* Timer notification messages. */
-	HVMSG_TIMER_EXPIRED			= 0x80000010,
+/* Timer notification messages. */
+#define HVMSG_TIMER_EXPIRED		0x80000010
 
-	/* Error messages. */
-	HVMSG_INVALID_VP_REGISTER_VALUE	= 0x80000020,
-	HVMSG_UNRECOVERABLE_EXCEPTION	= 0x80000021,
-	HVMSG_UNSUPPORTED_FEATURE		= 0x80000022,
+/* Error messages. */
+#define HVMSG_INVALID_VP_REGISTER_VALUE	0x80000020
+#define HVMSG_UNRECOVERABLE_EXCEPTION	0x80000021
+#define HVMSG_UNSUPPORTED_FEATURE	0x80000022
 
-	/* Trace buffer complete messages. */
-	HVMSG_EVENTLOG_BUFFERCOMPLETE	= 0x80000040,
+/* Trace buffer complete messages. */
+#define HVMSG_EVENTLOG_BUFFERCOMPLETE	0x80000040
 
-	/* Platform-specific processor intercept messages. */
-	HVMSG_X64_IOPORT_INTERCEPT		= 0x80010000,
-	HVMSG_X64_MSR_INTERCEPT		= 0x80010001,
-	HVMSG_X64_CPUID_INTERCEPT		= 0x80010002,
-	HVMSG_X64_EXCEPTION_INTERCEPT	= 0x80010003,
-	HVMSG_X64_APIC_EOI			= 0x80010004,
-	HVMSG_X64_LEGACY_FP_ERROR		= 0x80010005
-};
+/* Platform-specific processor intercept messages. */
+#define HVMSG_X64_IOPORT_INTERCEPT	0x80010000
+#define HVMSG_X64_MSR_INTERCEPT		0x80010001
+#define HVMSG_X64_CPUID_INTERCEPT	0x80010002
+#define HVMSG_X64_EXCEPTION_INTERCEPT	0x80010003
+#define HVMSG_X64_APIC_EOI		0x80010004
+#define HVMSG_X64_LEGACY_FP_ERROR	0x80010005
 
 #define HV_SYNIC_STIMER_COUNT		(4)
 
@@ -174,7 +172,7 @@ union hv_message_flags {
 
 /* Define synthetic interrupt controller message header. */
 struct hv_message_header {
-	enum hv_message_type message_type;
+	u32 message_type;
 	u8 payload_size;
 	union hv_message_flags message_flags;
 	u8 reserved[2];
@@ -347,7 +345,7 @@ enum hv_call_code {
 struct hv_input_post_message {
 	union hv_connection_id connectionid;
 	u32 reserved;
-	enum hv_message_type message_type;
+	u32 message_type;
 	u32 payload_size;
 	u64 payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
 };
@@ -579,8 +577,8 @@ extern int hv_init(void);
 extern void hv_cleanup(void);
 
 extern int hv_post_message(union hv_connection_id connection_id,
-			 enum hv_message_type message_type,
-			 void *payload, size_t payload_size);
+			   u32 message_type,
+			   void *payload, size_t payload_size);
 
 extern u16 hv_signal_event(void *con_id);
 
-- 
2.4.3

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

* [Qemu-devel] [PATCH v2 1/9] drivers/hv: replace enum hv_message_type by u32
@ 2015-11-30 16:22   ` Andrey Smetanin
  0 siblings, 0 replies; 34+ messages in thread
From: Andrey Smetanin @ 2015-11-30 16:22 UTC (permalink / raw)
  To: kvm
  Cc: Gleb Natapov, Haiyang Zhang, qemu-devel, Roman Kagan,
	Denis V. Lunev, Paolo Bonzini, Vitaly Kuznetsov,
	K. Y. Srinivasan

enum hv_message_type inside struct hv_message, hv_post_message
is not size portable. Replace enum by u32.

Signed-off-by: Andrey Smetanin <asmetanin@virtuozzo.com>
CC: Gleb Natapov <gleb@kernel.org>
CC: Paolo Bonzini <pbonzini@redhat.com>
CC: "K. Y. Srinivasan" <kys@microsoft.com>
CC: Haiyang Zhang <haiyangz@microsoft.com>
CC: Vitaly Kuznetsov <vkuznets@redhat.com>
CC: Roman Kagan <rkagan@virtuozzo.com>
CC: Denis V. Lunev <den@openvz.org>
CC: qemu-devel@nongnu.org

---
 drivers/hv/hv.c           |  4 ++--
 drivers/hv/hyperv_vmbus.h | 48 +++++++++++++++++++++++------------------------
 2 files changed, 25 insertions(+), 27 deletions(-)

diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
index 6341be8..dde7e1c 100644
--- a/drivers/hv/hv.c
+++ b/drivers/hv/hv.c
@@ -310,8 +310,8 @@ void hv_cleanup(void)
  * This involves a hypercall.
  */
 int hv_post_message(union hv_connection_id connection_id,
-		  enum hv_message_type message_type,
-		  void *payload, size_t payload_size)
+		    u32 message_type,
+		    void *payload, size_t payload_size)
 {
 
 	struct hv_input_post_message *aligned_msg;
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
index 3782636..e46e18c 100644
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -75,32 +75,30 @@ enum hv_cpuid_function {
 #define HV_EVENT_FLAGS_DWORD_COUNT	(256 / sizeof(u32))
 
 /* Define hypervisor message types. */
-enum hv_message_type {
-	HVMSG_NONE			= 0x00000000,
+#define HVMSG_NONE			0x00000000
 
-	/* Memory access messages. */
-	HVMSG_UNMAPPED_GPA		= 0x80000000,
-	HVMSG_GPA_INTERCEPT		= 0x80000001,
+/* Memory access messages. */
+#define HVMSG_UNMAPPED_GPA		0x80000000
+#define HVMSG_GPA_INTERCEPT		0x80000001
 
-	/* Timer notification messages. */
-	HVMSG_TIMER_EXPIRED			= 0x80000010,
+/* Timer notification messages. */
+#define HVMSG_TIMER_EXPIRED		0x80000010
 
-	/* Error messages. */
-	HVMSG_INVALID_VP_REGISTER_VALUE	= 0x80000020,
-	HVMSG_UNRECOVERABLE_EXCEPTION	= 0x80000021,
-	HVMSG_UNSUPPORTED_FEATURE		= 0x80000022,
+/* Error messages. */
+#define HVMSG_INVALID_VP_REGISTER_VALUE	0x80000020
+#define HVMSG_UNRECOVERABLE_EXCEPTION	0x80000021
+#define HVMSG_UNSUPPORTED_FEATURE	0x80000022
 
-	/* Trace buffer complete messages. */
-	HVMSG_EVENTLOG_BUFFERCOMPLETE	= 0x80000040,
+/* Trace buffer complete messages. */
+#define HVMSG_EVENTLOG_BUFFERCOMPLETE	0x80000040
 
-	/* Platform-specific processor intercept messages. */
-	HVMSG_X64_IOPORT_INTERCEPT		= 0x80010000,
-	HVMSG_X64_MSR_INTERCEPT		= 0x80010001,
-	HVMSG_X64_CPUID_INTERCEPT		= 0x80010002,
-	HVMSG_X64_EXCEPTION_INTERCEPT	= 0x80010003,
-	HVMSG_X64_APIC_EOI			= 0x80010004,
-	HVMSG_X64_LEGACY_FP_ERROR		= 0x80010005
-};
+/* Platform-specific processor intercept messages. */
+#define HVMSG_X64_IOPORT_INTERCEPT	0x80010000
+#define HVMSG_X64_MSR_INTERCEPT		0x80010001
+#define HVMSG_X64_CPUID_INTERCEPT	0x80010002
+#define HVMSG_X64_EXCEPTION_INTERCEPT	0x80010003
+#define HVMSG_X64_APIC_EOI		0x80010004
+#define HVMSG_X64_LEGACY_FP_ERROR	0x80010005
 
 #define HV_SYNIC_STIMER_COUNT		(4)
 
@@ -174,7 +172,7 @@ union hv_message_flags {
 
 /* Define synthetic interrupt controller message header. */
 struct hv_message_header {
-	enum hv_message_type message_type;
+	u32 message_type;
 	u8 payload_size;
 	union hv_message_flags message_flags;
 	u8 reserved[2];
@@ -347,7 +345,7 @@ enum hv_call_code {
 struct hv_input_post_message {
 	union hv_connection_id connectionid;
 	u32 reserved;
-	enum hv_message_type message_type;
+	u32 message_type;
 	u32 payload_size;
 	u64 payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
 };
@@ -579,8 +577,8 @@ extern int hv_init(void);
 extern void hv_cleanup(void);
 
 extern int hv_post_message(union hv_connection_id connection_id,
-			 enum hv_message_type message_type,
-			 void *payload, size_t payload_size);
+			   u32 message_type,
+			   void *payload, size_t payload_size);
 
 extern u16 hv_signal_event(void *con_id);
 
-- 
2.4.3

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

* [PATCH v2 2/9] drivers/hv: Move HV_SYNIC_STIMER_COUNT into Hyper-V UAPI x86 header
  2015-11-30 16:22 ` [Qemu-devel] " Andrey Smetanin
@ 2015-11-30 16:22   ` Andrey Smetanin
  -1 siblings, 0 replies; 34+ messages in thread
From: Andrey Smetanin @ 2015-11-30 16:22 UTC (permalink / raw)
  To: kvm
  Cc: Gleb Natapov, Haiyang Zhang, qemu-devel, Roman Kagan,
	Denis V. Lunev, Paolo Bonzini, Vitaly Kuznetsov,
	K. Y. Srinivasan

This constant is required for Hyper-V SynIC timers MSR's
support by userspace(QEMU).

Signed-off-by: Andrey Smetanin <asmetanin@virtuozzo.com>
Acked-by: K. Y. Srinivasan <kys@microsoft.com>
Reviewed-by: Roman Kagan <rkagan@virtuozzo.com>
CC: Gleb Natapov <gleb@kernel.org>
CC: Paolo Bonzini <pbonzini@redhat.com>
CC: "K. Y. Srinivasan" <kys@microsoft.com>
CC: Haiyang Zhang <haiyangz@microsoft.com>
CC: Vitaly Kuznetsov <vkuznets@redhat.com>
CC: Roman Kagan <rkagan@virtuozzo.com>
CC: Denis V. Lunev <den@openvz.org>
CC: qemu-devel@nongnu.org
---
 arch/x86/include/uapi/asm/hyperv.h | 2 ++
 drivers/hv/hyperv_vmbus.h          | 2 --
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/x86/include/uapi/asm/hyperv.h b/arch/x86/include/uapi/asm/hyperv.h
index 040d408..07981f0 100644
--- a/arch/x86/include/uapi/asm/hyperv.h
+++ b/arch/x86/include/uapi/asm/hyperv.h
@@ -269,4 +269,6 @@ typedef struct _HV_REFERENCE_TSC_PAGE {
 #define HV_SYNIC_SINT_AUTO_EOI		(1ULL << 17)
 #define HV_SYNIC_SINT_VECTOR_MASK	(0xFF)
 
+#define HV_SYNIC_STIMER_COUNT		(4)
+
 #endif
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
index e46e18c..f214e37 100644
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -100,8 +100,6 @@ enum hv_cpuid_function {
 #define HVMSG_X64_APIC_EOI		0x80010004
 #define HVMSG_X64_LEGACY_FP_ERROR	0x80010005
 
-#define HV_SYNIC_STIMER_COUNT		(4)
-
 /* Define invalid partition identifier. */
 #define HV_PARTITION_ID_INVALID		((u64)0x0)
 
-- 
2.4.3

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

* [Qemu-devel] [PATCH v2 2/9] drivers/hv: Move HV_SYNIC_STIMER_COUNT into Hyper-V UAPI x86 header
@ 2015-11-30 16:22   ` Andrey Smetanin
  0 siblings, 0 replies; 34+ messages in thread
From: Andrey Smetanin @ 2015-11-30 16:22 UTC (permalink / raw)
  To: kvm
  Cc: Gleb Natapov, Haiyang Zhang, qemu-devel, Roman Kagan,
	Denis V. Lunev, Paolo Bonzini, Vitaly Kuznetsov,
	K. Y. Srinivasan

This constant is required for Hyper-V SynIC timers MSR's
support by userspace(QEMU).

Signed-off-by: Andrey Smetanin <asmetanin@virtuozzo.com>
Acked-by: K. Y. Srinivasan <kys@microsoft.com>
Reviewed-by: Roman Kagan <rkagan@virtuozzo.com>
CC: Gleb Natapov <gleb@kernel.org>
CC: Paolo Bonzini <pbonzini@redhat.com>
CC: "K. Y. Srinivasan" <kys@microsoft.com>
CC: Haiyang Zhang <haiyangz@microsoft.com>
CC: Vitaly Kuznetsov <vkuznets@redhat.com>
CC: Roman Kagan <rkagan@virtuozzo.com>
CC: Denis V. Lunev <den@openvz.org>
CC: qemu-devel@nongnu.org
---
 arch/x86/include/uapi/asm/hyperv.h | 2 ++
 drivers/hv/hyperv_vmbus.h          | 2 --
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/x86/include/uapi/asm/hyperv.h b/arch/x86/include/uapi/asm/hyperv.h
index 040d408..07981f0 100644
--- a/arch/x86/include/uapi/asm/hyperv.h
+++ b/arch/x86/include/uapi/asm/hyperv.h
@@ -269,4 +269,6 @@ typedef struct _HV_REFERENCE_TSC_PAGE {
 #define HV_SYNIC_SINT_AUTO_EOI		(1ULL << 17)
 #define HV_SYNIC_SINT_VECTOR_MASK	(0xFF)
 
+#define HV_SYNIC_STIMER_COUNT		(4)
+
 #endif
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
index e46e18c..f214e37 100644
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -100,8 +100,6 @@ enum hv_cpuid_function {
 #define HVMSG_X64_APIC_EOI		0x80010004
 #define HVMSG_X64_LEGACY_FP_ERROR	0x80010005
 
-#define HV_SYNIC_STIMER_COUNT		(4)
-
 /* Define invalid partition identifier. */
 #define HV_PARTITION_ID_INVALID		((u64)0x0)
 
-- 
2.4.3

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

* [PATCH v2 3/9] drivers/hv: Move struct hv_message into UAPI Hyper-V x86 header
  2015-11-30 16:22 ` [Qemu-devel] " Andrey Smetanin
@ 2015-11-30 16:22   ` Andrey Smetanin
  -1 siblings, 0 replies; 34+ messages in thread
From: Andrey Smetanin @ 2015-11-30 16:22 UTC (permalink / raw)
  To: kvm
  Cc: Gleb Natapov, Paolo Bonzini, K. Y. Srinivasan, Haiyang Zhang,
	Vitaly Kuznetsov, Roman Kagan, Denis V. Lunev, qemu-devel

This struct is required for Hyper-V SynIC timers implementation inside KVM
and for upcoming Hyper-V VMBus support by userspace(QEMU). So place it into
Hyper-V UAPI header.

Signed-off-by: Andrey Smetanin <asmetanin@virtuozzo.com>
Acked-by: K. Y. Srinivasan <kys@microsoft.com>
Reviewed-by: Roman Kagan <rkagan@virtuozzo.com>
CC: Gleb Natapov <gleb@kernel.org>
CC: Paolo Bonzini <pbonzini@redhat.com>
CC: "K. Y. Srinivasan" <kys@microsoft.com>
CC: Haiyang Zhang <haiyangz@microsoft.com>
CC: Vitaly Kuznetsov <vkuznets@redhat.com>
CC: Roman Kagan <rkagan@virtuozzo.com>
CC: Denis V. Lunev <den@openvz.org>
CC: qemu-devel@nongnu.org
---
 arch/x86/include/uapi/asm/hyperv.h | 74 ++++++++++++++++++++++++++++++++++++++
 drivers/hv/hyperv_vmbus.h          | 73 -------------------------------------
 2 files changed, 74 insertions(+), 73 deletions(-)

diff --git a/arch/x86/include/uapi/asm/hyperv.h b/arch/x86/include/uapi/asm/hyperv.h
index 07981f0..76e503d 100644
--- a/arch/x86/include/uapi/asm/hyperv.h
+++ b/arch/x86/include/uapi/asm/hyperv.h
@@ -271,4 +271,78 @@ typedef struct _HV_REFERENCE_TSC_PAGE {
 
 #define HV_SYNIC_STIMER_COUNT		(4)
 
+/* Define synthetic interrupt controller message constants. */
+#define HV_MESSAGE_SIZE			(256)
+#define HV_MESSAGE_PAYLOAD_BYTE_COUNT	(240)
+#define HV_MESSAGE_PAYLOAD_QWORD_COUNT	(30)
+
+/* Define hypervisor message types. */
+#define HVMSG_NONE			0x00000000
+
+/* Memory access messages. */
+#define HVMSG_UNMAPPED_GPA		0x80000000
+#define HVMSG_GPA_INTERCEPT		0x80000001
+
+/* Timer notification messages. */
+#define HVMSG_TIMER_EXPIRED		0x80000010
+
+/* Error messages. */
+#define HVMSG_INVALID_VP_REGISTER_VALUE	0x80000020
+#define HVMSG_UNRECOVERABLE_EXCEPTION	0x80000021
+#define HVMSG_UNSUPPORTED_FEATURE	0x80000022
+
+/* Trace buffer complete messages. */
+#define HVMSG_EVENTLOG_BUFFERCOMPLETE	0x80000040
+
+/* Platform-specific processor intercept messages. */
+#define HVMSG_X64_IOPORT_INTERCEPT	0x80010000
+#define HVMSG_X64_MSR_INTERCEPT		0x80010001
+#define HVMSG_X64_CPUID_INTERCEPT	0x80010002
+#define HVMSG_X64_EXCEPTION_INTERCEPT	0x80010003
+#define HVMSG_X64_APIC_EOI		0x80010004
+#define HVMSG_X64_LEGACY_FP_ERROR	0x80010005
+
+/* Define synthetic interrupt controller message flags. */
+union hv_message_flags {
+	__u8 asu8;
+	struct {
+		__u8 msg_pending:1;
+		__u8 reserved:7;
+	};
+};
+
+/* Define port identifier type. */
+union hv_port_id {
+	__u32 asu32;
+	struct {
+		__u32 id:24;
+		__u32 reserved:8;
+	} u;
+};
+
+/* Define synthetic interrupt controller message header. */
+struct hv_message_header {
+	__u32 message_type;
+	__u8 payload_size;
+	union hv_message_flags message_flags;
+	__u8 reserved[2];
+	union {
+		__u64 sender;
+		union hv_port_id port;
+	};
+};
+
+/* Define synthetic interrupt controller message format. */
+struct hv_message {
+	struct hv_message_header header;
+	union {
+		__u64 payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
+	} u;
+};
+
+/* Define the synthetic interrupt message page layout. */
+struct hv_message_page {
+	struct hv_message sint_message[HV_SYNIC_SINT_COUNT];
+};
+
 #endif
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
index f214e37..3f3756b 100644
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -63,10 +63,6 @@ enum hv_cpuid_function {
 /* Define version of the synthetic interrupt controller. */
 #define HV_SYNIC_VERSION		(1)
 
-/* Define synthetic interrupt controller message constants. */
-#define HV_MESSAGE_SIZE			(256)
-#define HV_MESSAGE_PAYLOAD_BYTE_COUNT	(240)
-#define HV_MESSAGE_PAYLOAD_QWORD_COUNT	(30)
 #define HV_ANY_VP			(0xFFFFFFFF)
 
 /* Define synthetic interrupt controller flag constants. */
@@ -74,44 +70,9 @@ enum hv_cpuid_function {
 #define HV_EVENT_FLAGS_BYTE_COUNT	(256)
 #define HV_EVENT_FLAGS_DWORD_COUNT	(256 / sizeof(u32))
 
-/* Define hypervisor message types. */
-#define HVMSG_NONE			0x00000000
-
-/* Memory access messages. */
-#define HVMSG_UNMAPPED_GPA		0x80000000
-#define HVMSG_GPA_INTERCEPT		0x80000001
-
-/* Timer notification messages. */
-#define HVMSG_TIMER_EXPIRED		0x80000010
-
-/* Error messages. */
-#define HVMSG_INVALID_VP_REGISTER_VALUE	0x80000020
-#define HVMSG_UNRECOVERABLE_EXCEPTION	0x80000021
-#define HVMSG_UNSUPPORTED_FEATURE	0x80000022
-
-/* Trace buffer complete messages. */
-#define HVMSG_EVENTLOG_BUFFERCOMPLETE	0x80000040
-
-/* Platform-specific processor intercept messages. */
-#define HVMSG_X64_IOPORT_INTERCEPT	0x80010000
-#define HVMSG_X64_MSR_INTERCEPT		0x80010001
-#define HVMSG_X64_CPUID_INTERCEPT	0x80010002
-#define HVMSG_X64_EXCEPTION_INTERCEPT	0x80010003
-#define HVMSG_X64_APIC_EOI		0x80010004
-#define HVMSG_X64_LEGACY_FP_ERROR	0x80010005
-
 /* Define invalid partition identifier. */
 #define HV_PARTITION_ID_INVALID		((u64)0x0)
 
-/* Define port identifier type. */
-union hv_port_id {
-	u32 asu32;
-	struct {
-		u32 id:24;
-		u32 reserved:8;
-	} u ;
-};
-
 /* Define port type. */
 enum hv_port_type {
 	HVPORT_MSG	= 1,
@@ -159,27 +120,6 @@ struct hv_connection_info {
 	};
 };
 
-/* Define synthetic interrupt controller message flags. */
-union hv_message_flags {
-	u8 asu8;
-	struct {
-		u8 msg_pending:1;
-		u8 reserved:7;
-	};
-};
-
-/* Define synthetic interrupt controller message header. */
-struct hv_message_header {
-	u32 message_type;
-	u8 payload_size;
-	union hv_message_flags message_flags;
-	u8 reserved[2];
-	union {
-		u64 sender;
-		union hv_port_id port;
-	};
-};
-
 /*
  * Timer configuration register.
  */
@@ -205,22 +145,9 @@ struct hv_timer_message_payload {
 	u64 delivery_time;	/* When the message was delivered */
 };
 
-/* Define synthetic interrupt controller message format. */
-struct hv_message {
-	struct hv_message_header header;
-	union {
-		u64 payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
-	} u ;
-};
-
 /* Define the number of message buffers associated with each port. */
 #define HV_PORT_MESSAGE_BUFFER_COUNT	(16)
 
-/* Define the synthetic interrupt message page layout. */
-struct hv_message_page {
-	struct hv_message sint_message[HV_SYNIC_SINT_COUNT];
-};
-
 /* Define the synthetic interrupt controller event flags format. */
 union hv_synic_event_flags {
 	u8 flags8[HV_EVENT_FLAGS_BYTE_COUNT];
-- 
2.4.3


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

* [Qemu-devel] [PATCH v2 3/9] drivers/hv: Move struct hv_message into UAPI Hyper-V x86 header
@ 2015-11-30 16:22   ` Andrey Smetanin
  0 siblings, 0 replies; 34+ messages in thread
From: Andrey Smetanin @ 2015-11-30 16:22 UTC (permalink / raw)
  To: kvm
  Cc: Gleb Natapov, Haiyang Zhang, qemu-devel, Roman Kagan,
	Denis V. Lunev, Paolo Bonzini, Vitaly Kuznetsov,
	K. Y. Srinivasan

This struct is required for Hyper-V SynIC timers implementation inside KVM
and for upcoming Hyper-V VMBus support by userspace(QEMU). So place it into
Hyper-V UAPI header.

Signed-off-by: Andrey Smetanin <asmetanin@virtuozzo.com>
Acked-by: K. Y. Srinivasan <kys@microsoft.com>
Reviewed-by: Roman Kagan <rkagan@virtuozzo.com>
CC: Gleb Natapov <gleb@kernel.org>
CC: Paolo Bonzini <pbonzini@redhat.com>
CC: "K. Y. Srinivasan" <kys@microsoft.com>
CC: Haiyang Zhang <haiyangz@microsoft.com>
CC: Vitaly Kuznetsov <vkuznets@redhat.com>
CC: Roman Kagan <rkagan@virtuozzo.com>
CC: Denis V. Lunev <den@openvz.org>
CC: qemu-devel@nongnu.org
---
 arch/x86/include/uapi/asm/hyperv.h | 74 ++++++++++++++++++++++++++++++++++++++
 drivers/hv/hyperv_vmbus.h          | 73 -------------------------------------
 2 files changed, 74 insertions(+), 73 deletions(-)

diff --git a/arch/x86/include/uapi/asm/hyperv.h b/arch/x86/include/uapi/asm/hyperv.h
index 07981f0..76e503d 100644
--- a/arch/x86/include/uapi/asm/hyperv.h
+++ b/arch/x86/include/uapi/asm/hyperv.h
@@ -271,4 +271,78 @@ typedef struct _HV_REFERENCE_TSC_PAGE {
 
 #define HV_SYNIC_STIMER_COUNT		(4)
 
+/* Define synthetic interrupt controller message constants. */
+#define HV_MESSAGE_SIZE			(256)
+#define HV_MESSAGE_PAYLOAD_BYTE_COUNT	(240)
+#define HV_MESSAGE_PAYLOAD_QWORD_COUNT	(30)
+
+/* Define hypervisor message types. */
+#define HVMSG_NONE			0x00000000
+
+/* Memory access messages. */
+#define HVMSG_UNMAPPED_GPA		0x80000000
+#define HVMSG_GPA_INTERCEPT		0x80000001
+
+/* Timer notification messages. */
+#define HVMSG_TIMER_EXPIRED		0x80000010
+
+/* Error messages. */
+#define HVMSG_INVALID_VP_REGISTER_VALUE	0x80000020
+#define HVMSG_UNRECOVERABLE_EXCEPTION	0x80000021
+#define HVMSG_UNSUPPORTED_FEATURE	0x80000022
+
+/* Trace buffer complete messages. */
+#define HVMSG_EVENTLOG_BUFFERCOMPLETE	0x80000040
+
+/* Platform-specific processor intercept messages. */
+#define HVMSG_X64_IOPORT_INTERCEPT	0x80010000
+#define HVMSG_X64_MSR_INTERCEPT		0x80010001
+#define HVMSG_X64_CPUID_INTERCEPT	0x80010002
+#define HVMSG_X64_EXCEPTION_INTERCEPT	0x80010003
+#define HVMSG_X64_APIC_EOI		0x80010004
+#define HVMSG_X64_LEGACY_FP_ERROR	0x80010005
+
+/* Define synthetic interrupt controller message flags. */
+union hv_message_flags {
+	__u8 asu8;
+	struct {
+		__u8 msg_pending:1;
+		__u8 reserved:7;
+	};
+};
+
+/* Define port identifier type. */
+union hv_port_id {
+	__u32 asu32;
+	struct {
+		__u32 id:24;
+		__u32 reserved:8;
+	} u;
+};
+
+/* Define synthetic interrupt controller message header. */
+struct hv_message_header {
+	__u32 message_type;
+	__u8 payload_size;
+	union hv_message_flags message_flags;
+	__u8 reserved[2];
+	union {
+		__u64 sender;
+		union hv_port_id port;
+	};
+};
+
+/* Define synthetic interrupt controller message format. */
+struct hv_message {
+	struct hv_message_header header;
+	union {
+		__u64 payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
+	} u;
+};
+
+/* Define the synthetic interrupt message page layout. */
+struct hv_message_page {
+	struct hv_message sint_message[HV_SYNIC_SINT_COUNT];
+};
+
 #endif
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
index f214e37..3f3756b 100644
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -63,10 +63,6 @@ enum hv_cpuid_function {
 /* Define version of the synthetic interrupt controller. */
 #define HV_SYNIC_VERSION		(1)
 
-/* Define synthetic interrupt controller message constants. */
-#define HV_MESSAGE_SIZE			(256)
-#define HV_MESSAGE_PAYLOAD_BYTE_COUNT	(240)
-#define HV_MESSAGE_PAYLOAD_QWORD_COUNT	(30)
 #define HV_ANY_VP			(0xFFFFFFFF)
 
 /* Define synthetic interrupt controller flag constants. */
@@ -74,44 +70,9 @@ enum hv_cpuid_function {
 #define HV_EVENT_FLAGS_BYTE_COUNT	(256)
 #define HV_EVENT_FLAGS_DWORD_COUNT	(256 / sizeof(u32))
 
-/* Define hypervisor message types. */
-#define HVMSG_NONE			0x00000000
-
-/* Memory access messages. */
-#define HVMSG_UNMAPPED_GPA		0x80000000
-#define HVMSG_GPA_INTERCEPT		0x80000001
-
-/* Timer notification messages. */
-#define HVMSG_TIMER_EXPIRED		0x80000010
-
-/* Error messages. */
-#define HVMSG_INVALID_VP_REGISTER_VALUE	0x80000020
-#define HVMSG_UNRECOVERABLE_EXCEPTION	0x80000021
-#define HVMSG_UNSUPPORTED_FEATURE	0x80000022
-
-/* Trace buffer complete messages. */
-#define HVMSG_EVENTLOG_BUFFERCOMPLETE	0x80000040
-
-/* Platform-specific processor intercept messages. */
-#define HVMSG_X64_IOPORT_INTERCEPT	0x80010000
-#define HVMSG_X64_MSR_INTERCEPT		0x80010001
-#define HVMSG_X64_CPUID_INTERCEPT	0x80010002
-#define HVMSG_X64_EXCEPTION_INTERCEPT	0x80010003
-#define HVMSG_X64_APIC_EOI		0x80010004
-#define HVMSG_X64_LEGACY_FP_ERROR	0x80010005
-
 /* Define invalid partition identifier. */
 #define HV_PARTITION_ID_INVALID		((u64)0x0)
 
-/* Define port identifier type. */
-union hv_port_id {
-	u32 asu32;
-	struct {
-		u32 id:24;
-		u32 reserved:8;
-	} u ;
-};
-
 /* Define port type. */
 enum hv_port_type {
 	HVPORT_MSG	= 1,
@@ -159,27 +120,6 @@ struct hv_connection_info {
 	};
 };
 
-/* Define synthetic interrupt controller message flags. */
-union hv_message_flags {
-	u8 asu8;
-	struct {
-		u8 msg_pending:1;
-		u8 reserved:7;
-	};
-};
-
-/* Define synthetic interrupt controller message header. */
-struct hv_message_header {
-	u32 message_type;
-	u8 payload_size;
-	union hv_message_flags message_flags;
-	u8 reserved[2];
-	union {
-		u64 sender;
-		union hv_port_id port;
-	};
-};
-
 /*
  * Timer configuration register.
  */
@@ -205,22 +145,9 @@ struct hv_timer_message_payload {
 	u64 delivery_time;	/* When the message was delivered */
 };
 
-/* Define synthetic interrupt controller message format. */
-struct hv_message {
-	struct hv_message_header header;
-	union {
-		u64 payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
-	} u ;
-};
-
 /* Define the number of message buffers associated with each port. */
 #define HV_PORT_MESSAGE_BUFFER_COUNT	(16)
 
-/* Define the synthetic interrupt message page layout. */
-struct hv_message_page {
-	struct hv_message sint_message[HV_SYNIC_SINT_COUNT];
-};
-
 /* Define the synthetic interrupt controller event flags format. */
 union hv_synic_event_flags {
 	u8 flags8[HV_EVENT_FLAGS_BYTE_COUNT];
-- 
2.4.3

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

* [PATCH v2 4/9] drivers/hv: Move struct hv_timer_message_payload into UAPI Hyper-V x86 header
  2015-11-30 16:22 ` [Qemu-devel] " Andrey Smetanin
@ 2015-11-30 16:22   ` Andrey Smetanin
  -1 siblings, 0 replies; 34+ messages in thread
From: Andrey Smetanin @ 2015-11-30 16:22 UTC (permalink / raw)
  To: kvm
  Cc: Gleb Natapov, Paolo Bonzini, K. Y. Srinivasan, Haiyang Zhang,
	Vitaly Kuznetsov, Roman Kagan, Denis V. Lunev, qemu-devel

This struct is required for Hyper-V SynIC timers implementation inside KVM
and for upcoming Hyper-V VMBus support by userspace(QEMU). So place it into
Hyper-V UAPI header.

Signed-off-by: Andrey Smetanin <asmetanin@virtuozzo.com>
CC: Gleb Natapov <gleb@kernel.org>
CC: Paolo Bonzini <pbonzini@redhat.com>
CC: "K. Y. Srinivasan" <kys@microsoft.com>
CC: Haiyang Zhang <haiyangz@microsoft.com>
CC: Vitaly Kuznetsov <vkuznets@redhat.com>
CC: Roman Kagan <rkagan@virtuozzo.com>
CC: Denis V. Lunev <den@openvz.org>
CC: qemu-devel@nongnu.org

---
 arch/x86/include/uapi/asm/hyperv.h | 8 ++++++++
 drivers/hv/hyperv_vmbus.h          | 9 ---------
 2 files changed, 8 insertions(+), 9 deletions(-)

diff --git a/arch/x86/include/uapi/asm/hyperv.h b/arch/x86/include/uapi/asm/hyperv.h
index 76e503d..42278f8 100644
--- a/arch/x86/include/uapi/asm/hyperv.h
+++ b/arch/x86/include/uapi/asm/hyperv.h
@@ -345,4 +345,12 @@ struct hv_message_page {
 	struct hv_message sint_message[HV_SYNIC_SINT_COUNT];
 };
 
+/* Define timer message payload structure. */
+struct hv_timer_message_payload {
+	__u32 timer_index;
+	__u32 reserved;
+	__u64 expiration_time;	/* When the timer expired */
+	__u64 delivery_time;	/* When the message was delivered */
+};
+
 #endif
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
index 3f3756b..db60080 100644
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -136,15 +136,6 @@ union hv_timer_config {
 	};
 };
 
-
-/* Define timer message payload structure. */
-struct hv_timer_message_payload {
-	u32 timer_index;
-	u32 reserved;
-	u64 expiration_time;	/* When the timer expired */
-	u64 delivery_time;	/* When the message was delivered */
-};
-
 /* Define the number of message buffers associated with each port. */
 #define HV_PORT_MESSAGE_BUFFER_COUNT	(16)
 
-- 
2.4.3


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

* [Qemu-devel] [PATCH v2 4/9] drivers/hv: Move struct hv_timer_message_payload into UAPI Hyper-V x86 header
@ 2015-11-30 16:22   ` Andrey Smetanin
  0 siblings, 0 replies; 34+ messages in thread
From: Andrey Smetanin @ 2015-11-30 16:22 UTC (permalink / raw)
  To: kvm
  Cc: Gleb Natapov, Haiyang Zhang, qemu-devel, Roman Kagan,
	Denis V. Lunev, Paolo Bonzini, Vitaly Kuznetsov,
	K. Y. Srinivasan

This struct is required for Hyper-V SynIC timers implementation inside KVM
and for upcoming Hyper-V VMBus support by userspace(QEMU). So place it into
Hyper-V UAPI header.

Signed-off-by: Andrey Smetanin <asmetanin@virtuozzo.com>
CC: Gleb Natapov <gleb@kernel.org>
CC: Paolo Bonzini <pbonzini@redhat.com>
CC: "K. Y. Srinivasan" <kys@microsoft.com>
CC: Haiyang Zhang <haiyangz@microsoft.com>
CC: Vitaly Kuznetsov <vkuznets@redhat.com>
CC: Roman Kagan <rkagan@virtuozzo.com>
CC: Denis V. Lunev <den@openvz.org>
CC: qemu-devel@nongnu.org

---
 arch/x86/include/uapi/asm/hyperv.h | 8 ++++++++
 drivers/hv/hyperv_vmbus.h          | 9 ---------
 2 files changed, 8 insertions(+), 9 deletions(-)

diff --git a/arch/x86/include/uapi/asm/hyperv.h b/arch/x86/include/uapi/asm/hyperv.h
index 76e503d..42278f8 100644
--- a/arch/x86/include/uapi/asm/hyperv.h
+++ b/arch/x86/include/uapi/asm/hyperv.h
@@ -345,4 +345,12 @@ struct hv_message_page {
 	struct hv_message sint_message[HV_SYNIC_SINT_COUNT];
 };
 
+/* Define timer message payload structure. */
+struct hv_timer_message_payload {
+	__u32 timer_index;
+	__u32 reserved;
+	__u64 expiration_time;	/* When the timer expired */
+	__u64 delivery_time;	/* When the message was delivered */
+};
+
 #endif
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
index 3f3756b..db60080 100644
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -136,15 +136,6 @@ union hv_timer_config {
 	};
 };
 
-
-/* Define timer message payload structure. */
-struct hv_timer_message_payload {
-	u32 timer_index;
-	u32 reserved;
-	u64 expiration_time;	/* When the timer expired */
-	u64 delivery_time;	/* When the message was delivered */
-};
-
 /* Define the number of message buffers associated with each port. */
 #define HV_PORT_MESSAGE_BUFFER_COUNT	(16)
 
-- 
2.4.3

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

* [PATCH v2 5/9] kvm/x86: Rearrange func's declarations inside Hyper-V header
  2015-11-30 16:22 ` [Qemu-devel] " Andrey Smetanin
@ 2015-11-30 16:22   ` Andrey Smetanin
  -1 siblings, 0 replies; 34+ messages in thread
From: Andrey Smetanin @ 2015-11-30 16:22 UTC (permalink / raw)
  To: kvm
  Cc: Gleb Natapov, Haiyang Zhang, qemu-devel, Roman Kagan,
	Denis V. Lunev, Paolo Bonzini, Vitaly Kuznetsov,
	K. Y. Srinivasan

This rearrangement places functions declarations together
according to their functionality, so future additions
will be simplier.

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: "K. Y. Srinivasan" <kys@microsoft.com>
CC: Haiyang Zhang <haiyangz@microsoft.com>
CC: Vitaly Kuznetsov <vkuznets@redhat.com>
CC: Roman Kagan <rkagan@virtuozzo.com>
CC: Denis V. Lunev <den@openvz.org>
CC: qemu-devel@nongnu.org
---
 arch/x86/kvm/hyperv.h | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/arch/x86/kvm/hyperv.h b/arch/x86/kvm/hyperv.h
index 315af4b..9483d49 100644
--- a/arch/x86/kvm/hyperv.h
+++ b/arch/x86/kvm/hyperv.h
@@ -24,14 +24,6 @@
 #ifndef __ARCH_X86_KVM_HYPERV_H__
 #define __ARCH_X86_KVM_HYPERV_H__
 
-int kvm_hv_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data, bool host);
-int kvm_hv_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata);
-bool kvm_hv_hypercall_enabled(struct kvm *kvm);
-int kvm_hv_hypercall(struct kvm_vcpu *vcpu);
-
-int kvm_hv_synic_set_irq(struct kvm *kvm, u32 vcpu_id, u32 sint);
-void kvm_hv_synic_send_eoi(struct kvm_vcpu *vcpu, int vector);
-
 static inline struct kvm_vcpu_hv_synic *vcpu_to_synic(struct kvm_vcpu *vcpu)
 {
 	return &vcpu->arch.hyperv.synic;
@@ -46,10 +38,18 @@ static inline struct kvm_vcpu *synic_to_vcpu(struct kvm_vcpu_hv_synic *synic)
 	arch = container_of(hv, struct kvm_vcpu_arch, hyperv);
 	return container_of(arch, struct kvm_vcpu, arch);
 }
-void kvm_hv_irq_routing_update(struct kvm *kvm);
 
-void kvm_hv_vcpu_init(struct kvm_vcpu *vcpu);
+int kvm_hv_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data, bool host);
+int kvm_hv_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata);
+
+bool kvm_hv_hypercall_enabled(struct kvm *kvm);
+int kvm_hv_hypercall(struct kvm_vcpu *vcpu);
 
+void kvm_hv_irq_routing_update(struct kvm *kvm);
+int kvm_hv_synic_set_irq(struct kvm *kvm, u32 vcpu_id, u32 sint);
+void kvm_hv_synic_send_eoi(struct kvm_vcpu *vcpu, int vector);
 int kvm_hv_activate_synic(struct kvm_vcpu *vcpu);
 
+void kvm_hv_vcpu_init(struct kvm_vcpu *vcpu);
+
 #endif
-- 
2.4.3

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

* [Qemu-devel] [PATCH v2 5/9] kvm/x86: Rearrange func's declarations inside Hyper-V header
@ 2015-11-30 16:22   ` Andrey Smetanin
  0 siblings, 0 replies; 34+ messages in thread
From: Andrey Smetanin @ 2015-11-30 16:22 UTC (permalink / raw)
  To: kvm
  Cc: Gleb Natapov, Haiyang Zhang, qemu-devel, Roman Kagan,
	Denis V. Lunev, Paolo Bonzini, Vitaly Kuznetsov,
	K. Y. Srinivasan

This rearrangement places functions declarations together
according to their functionality, so future additions
will be simplier.

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: "K. Y. Srinivasan" <kys@microsoft.com>
CC: Haiyang Zhang <haiyangz@microsoft.com>
CC: Vitaly Kuznetsov <vkuznets@redhat.com>
CC: Roman Kagan <rkagan@virtuozzo.com>
CC: Denis V. Lunev <den@openvz.org>
CC: qemu-devel@nongnu.org
---
 arch/x86/kvm/hyperv.h | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/arch/x86/kvm/hyperv.h b/arch/x86/kvm/hyperv.h
index 315af4b..9483d49 100644
--- a/arch/x86/kvm/hyperv.h
+++ b/arch/x86/kvm/hyperv.h
@@ -24,14 +24,6 @@
 #ifndef __ARCH_X86_KVM_HYPERV_H__
 #define __ARCH_X86_KVM_HYPERV_H__
 
-int kvm_hv_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data, bool host);
-int kvm_hv_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata);
-bool kvm_hv_hypercall_enabled(struct kvm *kvm);
-int kvm_hv_hypercall(struct kvm_vcpu *vcpu);
-
-int kvm_hv_synic_set_irq(struct kvm *kvm, u32 vcpu_id, u32 sint);
-void kvm_hv_synic_send_eoi(struct kvm_vcpu *vcpu, int vector);
-
 static inline struct kvm_vcpu_hv_synic *vcpu_to_synic(struct kvm_vcpu *vcpu)
 {
 	return &vcpu->arch.hyperv.synic;
@@ -46,10 +38,18 @@ static inline struct kvm_vcpu *synic_to_vcpu(struct kvm_vcpu_hv_synic *synic)
 	arch = container_of(hv, struct kvm_vcpu_arch, hyperv);
 	return container_of(arch, struct kvm_vcpu, arch);
 }
-void kvm_hv_irq_routing_update(struct kvm *kvm);
 
-void kvm_hv_vcpu_init(struct kvm_vcpu *vcpu);
+int kvm_hv_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data, bool host);
+int kvm_hv_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata);
+
+bool kvm_hv_hypercall_enabled(struct kvm *kvm);
+int kvm_hv_hypercall(struct kvm_vcpu *vcpu);
 
+void kvm_hv_irq_routing_update(struct kvm *kvm);
+int kvm_hv_synic_set_irq(struct kvm *kvm, u32 vcpu_id, u32 sint);
+void kvm_hv_synic_send_eoi(struct kvm_vcpu *vcpu, int vector);
 int kvm_hv_activate_synic(struct kvm_vcpu *vcpu);
 
+void kvm_hv_vcpu_init(struct kvm_vcpu *vcpu);
+
 #endif
-- 
2.4.3

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

* [PATCH v2 6/9] kvm/x86: Added Hyper-V vcpu_to_hv_vcpu()/hv_vcpu_to_vcpu() helpers
  2015-11-30 16:22 ` [Qemu-devel] " Andrey Smetanin
@ 2015-11-30 16:22   ` Andrey Smetanin
  -1 siblings, 0 replies; 34+ messages in thread
From: Andrey Smetanin @ 2015-11-30 16:22 UTC (permalink / raw)
  To: kvm
  Cc: Gleb Natapov, Haiyang Zhang, qemu-devel, Roman Kagan,
	Denis V. Lunev, Paolo Bonzini, Vitaly Kuznetsov,
	K. Y. Srinivasan

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: "K. Y. Srinivasan" <kys@microsoft.com>
CC: Haiyang Zhang <haiyangz@microsoft.com>
CC: Vitaly Kuznetsov <vkuznets@redhat.com>
CC: Roman Kagan <rkagan@virtuozzo.com>
CC: Denis V. Lunev <den@openvz.org>
CC: qemu-devel@nongnu.org
---
 arch/x86/kvm/hyperv.h | 20 ++++++++++++++------
 1 file changed, 14 insertions(+), 6 deletions(-)

diff --git a/arch/x86/kvm/hyperv.h b/arch/x86/kvm/hyperv.h
index 9483d49..d5d8217 100644
--- a/arch/x86/kvm/hyperv.h
+++ b/arch/x86/kvm/hyperv.h
@@ -24,21 +24,29 @@
 #ifndef __ARCH_X86_KVM_HYPERV_H__
 #define __ARCH_X86_KVM_HYPERV_H__
 
-static inline struct kvm_vcpu_hv_synic *vcpu_to_synic(struct kvm_vcpu *vcpu)
+static inline struct kvm_vcpu_hv *vcpu_to_hv_vcpu(struct kvm_vcpu *vcpu)
 {
-	return &vcpu->arch.hyperv.synic;
+	return &vcpu->arch.hyperv;
 }
 
-static inline struct kvm_vcpu *synic_to_vcpu(struct kvm_vcpu_hv_synic *synic)
+static inline struct kvm_vcpu *hv_vcpu_to_vcpu(struct kvm_vcpu_hv *hv_vcpu)
 {
-	struct kvm_vcpu_hv *hv;
 	struct kvm_vcpu_arch *arch;
 
-	hv = container_of(synic, struct kvm_vcpu_hv, synic);
-	arch = container_of(hv, struct kvm_vcpu_arch, hyperv);
+	arch = container_of(hv_vcpu, struct kvm_vcpu_arch, hyperv);
 	return container_of(arch, struct kvm_vcpu, arch);
 }
 
+static inline struct kvm_vcpu_hv_synic *vcpu_to_synic(struct kvm_vcpu *vcpu)
+{
+	return &vcpu->arch.hyperv.synic;
+}
+
+static inline struct kvm_vcpu *synic_to_vcpu(struct kvm_vcpu_hv_synic *synic)
+{
+	return hv_vcpu_to_vcpu(container_of(synic, struct kvm_vcpu_hv, synic));
+}
+
 int kvm_hv_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data, bool host);
 int kvm_hv_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata);
 
-- 
2.4.3

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

* [Qemu-devel] [PATCH v2 6/9] kvm/x86: Added Hyper-V vcpu_to_hv_vcpu()/hv_vcpu_to_vcpu() helpers
@ 2015-11-30 16:22   ` Andrey Smetanin
  0 siblings, 0 replies; 34+ messages in thread
From: Andrey Smetanin @ 2015-11-30 16:22 UTC (permalink / raw)
  To: kvm
  Cc: Gleb Natapov, Haiyang Zhang, qemu-devel, Roman Kagan,
	Denis V. Lunev, Paolo Bonzini, Vitaly Kuznetsov,
	K. Y. Srinivasan

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: "K. Y. Srinivasan" <kys@microsoft.com>
CC: Haiyang Zhang <haiyangz@microsoft.com>
CC: Vitaly Kuznetsov <vkuznets@redhat.com>
CC: Roman Kagan <rkagan@virtuozzo.com>
CC: Denis V. Lunev <den@openvz.org>
CC: qemu-devel@nongnu.org
---
 arch/x86/kvm/hyperv.h | 20 ++++++++++++++------
 1 file changed, 14 insertions(+), 6 deletions(-)

diff --git a/arch/x86/kvm/hyperv.h b/arch/x86/kvm/hyperv.h
index 9483d49..d5d8217 100644
--- a/arch/x86/kvm/hyperv.h
+++ b/arch/x86/kvm/hyperv.h
@@ -24,21 +24,29 @@
 #ifndef __ARCH_X86_KVM_HYPERV_H__
 #define __ARCH_X86_KVM_HYPERV_H__
 
-static inline struct kvm_vcpu_hv_synic *vcpu_to_synic(struct kvm_vcpu *vcpu)
+static inline struct kvm_vcpu_hv *vcpu_to_hv_vcpu(struct kvm_vcpu *vcpu)
 {
-	return &vcpu->arch.hyperv.synic;
+	return &vcpu->arch.hyperv;
 }
 
-static inline struct kvm_vcpu *synic_to_vcpu(struct kvm_vcpu_hv_synic *synic)
+static inline struct kvm_vcpu *hv_vcpu_to_vcpu(struct kvm_vcpu_hv *hv_vcpu)
 {
-	struct kvm_vcpu_hv *hv;
 	struct kvm_vcpu_arch *arch;
 
-	hv = container_of(synic, struct kvm_vcpu_hv, synic);
-	arch = container_of(hv, struct kvm_vcpu_arch, hyperv);
+	arch = container_of(hv_vcpu, struct kvm_vcpu_arch, hyperv);
 	return container_of(arch, struct kvm_vcpu, arch);
 }
 
+static inline struct kvm_vcpu_hv_synic *vcpu_to_synic(struct kvm_vcpu *vcpu)
+{
+	return &vcpu->arch.hyperv.synic;
+}
+
+static inline struct kvm_vcpu *synic_to_vcpu(struct kvm_vcpu_hv_synic *synic)
+{
+	return hv_vcpu_to_vcpu(container_of(synic, struct kvm_vcpu_hv, synic));
+}
+
 int kvm_hv_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data, bool host);
 int kvm_hv_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata);
 
-- 
2.4.3

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

* [PATCH v2 7/9] kvm/x86: Hyper-V internal helper to read MSR HV_X64_MSR_TIME_REF_COUNT
  2015-11-30 16:22 ` [Qemu-devel] " Andrey Smetanin
@ 2015-11-30 16:22   ` Andrey Smetanin
  -1 siblings, 0 replies; 34+ messages in thread
From: Andrey Smetanin @ 2015-11-30 16:22 UTC (permalink / raw)
  To: kvm
  Cc: Gleb Natapov, Haiyang Zhang, qemu-devel, Roman Kagan,
	Denis V. Lunev, Paolo Bonzini, Vitaly Kuznetsov,
	K. Y. Srinivasan

This helper will be used also in Hyper-V SynIC timers implementation.

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: "K. Y. Srinivasan" <kys@microsoft.com>
CC: Haiyang Zhang <haiyangz@microsoft.com>
CC: Vitaly Kuznetsov <vkuznets@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 | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index 41869a9..9958926 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -335,6 +335,11 @@ static void synic_init(struct kvm_vcpu_hv_synic *synic)
 	}
 }
 
+static u64 get_time_ref_counter(struct kvm *kvm)
+{
+	return div_u64(get_kernel_ns() + kvm->arch.kvmclock_offset, 100);
+}
+
 void kvm_hv_vcpu_init(struct kvm_vcpu *vcpu)
 {
 	synic_init(vcpu_to_synic(vcpu));
@@ -576,11 +581,9 @@ static int kvm_hv_get_msr_pw(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
 	case HV_X64_MSR_HYPERCALL:
 		data = hv->hv_hypercall;
 		break;
-	case HV_X64_MSR_TIME_REF_COUNT: {
-		data =
-		     div_u64(get_kernel_ns() + kvm->arch.kvmclock_offset, 100);
+	case HV_X64_MSR_TIME_REF_COUNT:
+		data = get_time_ref_counter(kvm);
 		break;
-	}
 	case HV_X64_MSR_REFERENCE_TSC:
 		data = hv->hv_tsc_page;
 		break;
-- 
2.4.3

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

* [Qemu-devel] [PATCH v2 7/9] kvm/x86: Hyper-V internal helper to read MSR HV_X64_MSR_TIME_REF_COUNT
@ 2015-11-30 16:22   ` Andrey Smetanin
  0 siblings, 0 replies; 34+ messages in thread
From: Andrey Smetanin @ 2015-11-30 16:22 UTC (permalink / raw)
  To: kvm
  Cc: Gleb Natapov, Haiyang Zhang, qemu-devel, Roman Kagan,
	Denis V. Lunev, Paolo Bonzini, Vitaly Kuznetsov,
	K. Y. Srinivasan

This helper will be used also in Hyper-V SynIC timers implementation.

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: "K. Y. Srinivasan" <kys@microsoft.com>
CC: Haiyang Zhang <haiyangz@microsoft.com>
CC: Vitaly Kuznetsov <vkuznets@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 | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index 41869a9..9958926 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -335,6 +335,11 @@ static void synic_init(struct kvm_vcpu_hv_synic *synic)
 	}
 }
 
+static u64 get_time_ref_counter(struct kvm *kvm)
+{
+	return div_u64(get_kernel_ns() + kvm->arch.kvmclock_offset, 100);
+}
+
 void kvm_hv_vcpu_init(struct kvm_vcpu *vcpu)
 {
 	synic_init(vcpu_to_synic(vcpu));
@@ -576,11 +581,9 @@ static int kvm_hv_get_msr_pw(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
 	case HV_X64_MSR_HYPERCALL:
 		data = hv->hv_hypercall;
 		break;
-	case HV_X64_MSR_TIME_REF_COUNT: {
-		data =
-		     div_u64(get_kernel_ns() + kvm->arch.kvmclock_offset, 100);
+	case HV_X64_MSR_TIME_REF_COUNT:
+		data = get_time_ref_counter(kvm);
 		break;
-	}
 	case HV_X64_MSR_REFERENCE_TSC:
 		data = hv->hv_tsc_page;
 		break;
-- 
2.4.3

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

* [PATCH v2 8/9] kvm/x86: Hyper-V SynIC message slot pending clearing at SINT ack
  2015-11-30 16:22 ` [Qemu-devel] " Andrey Smetanin
@ 2015-11-30 16:22   ` Andrey Smetanin
  -1 siblings, 0 replies; 34+ messages in thread
From: Andrey Smetanin @ 2015-11-30 16:22 UTC (permalink / raw)
  To: kvm
  Cc: Gleb Natapov, Paolo Bonzini, K. Y. Srinivasan, Haiyang Zhang,
	Vitaly Kuznetsov, Roman Kagan, Denis V. Lunev, qemu-devel

The SynIC message protocol mandates that the message slot is claimed
by atomically setting message type to something other than HVMSG_NONE.
If another message is to be delivered while the slot is still busy,
message pending flag is asserted to indicate to the guest that the
hypervisor wants to be notified when the slot is released.

To make sure the protocol works regardless of where the message
sources are (kernel or userspace), clear the pending flag on SINT ACK
notification, and let the message sources compete for the slot again.

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: "K. Y. Srinivasan" <kys@microsoft.com>
CC: Haiyang Zhang <haiyangz@microsoft.com>
CC: Vitaly Kuznetsov <vkuznets@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    | 31 +++++++++++++++++++++++++++++++
 include/linux/kvm_host.h |  2 ++
 2 files changed, 33 insertions(+)

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index 9958926..6412b6b 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -27,6 +27,7 @@
 #include "hyperv.h"
 
 #include <linux/kvm_host.h>
+#include <linux/highmem.h>
 #include <asm/apicdef.h>
 #include <trace/events/kvm.h>
 
@@ -116,13 +117,43 @@ static struct kvm_vcpu_hv_synic *synic_get(struct kvm *kvm, u32 vcpu_id)
 	return (synic->active) ? synic : NULL;
 }
 
+static void synic_clear_sint_msg_pending(struct kvm_vcpu_hv_synic *synic,
+					u32 sint)
+{
+	struct kvm_vcpu *vcpu = synic_to_vcpu(synic);
+	struct page *page;
+	gpa_t gpa;
+	struct hv_message *msg;
+	struct hv_message_page *msg_page;
+
+	gpa = synic->msg_page & PAGE_MASK;
+	page = kvm_vcpu_gfn_to_page(vcpu, gpa >> PAGE_SHIFT);
+	if (is_error_page(page)) {
+		vcpu_err(vcpu, "Hyper-V SynIC can't get msg page, gpa 0x%llx\n",
+			 gpa);
+		return;
+	}
+	msg_page = kmap_atomic(page);
+
+	msg = &msg_page->sint_message[sint];
+	msg->header.message_flags.msg_pending = 0;
+
+	kunmap_atomic(msg_page);
+	kvm_release_page_dirty(page);
+	kvm_vcpu_mark_page_dirty(vcpu, gpa >> PAGE_SHIFT);
+}
+
 static void kvm_hv_notify_acked_sint(struct kvm_vcpu *vcpu, u32 sint)
 {
 	struct kvm *kvm = vcpu->kvm;
+	struct kvm_vcpu_hv_synic *synic = vcpu_to_synic(vcpu);
 	int gsi, idx;
 
 	vcpu_debug(vcpu, "Hyper-V SynIC acked sint %d\n", sint);
 
+	if (synic->msg_page & HV_SYNIC_SIMP_ENABLE)
+		synic_clear_sint_msg_pending(synic, sint);
+
 	idx = srcu_read_lock(&kvm->irq_srcu);
 	gsi = atomic_read(&vcpu_to_synic(vcpu)->sint_to_gsi[sint]);
 	if (gsi != -1)
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 2911919..9b64c8c 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -450,6 +450,8 @@ struct kvm {
 
 #define vcpu_debug(vcpu, fmt, ...)					\
 	kvm_debug("vcpu%i " fmt, (vcpu)->vcpu_id, ## __VA_ARGS__)
+#define vcpu_err(vcpu, fmt, ...)					\
+	kvm_err("vcpu%i " fmt, (vcpu)->vcpu_id, ## __VA_ARGS__)
 
 static inline struct kvm_vcpu *kvm_get_vcpu(struct kvm *kvm, int i)
 {
-- 
2.4.3


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

* [Qemu-devel] [PATCH v2 8/9] kvm/x86: Hyper-V SynIC message slot pending clearing at SINT ack
@ 2015-11-30 16:22   ` Andrey Smetanin
  0 siblings, 0 replies; 34+ messages in thread
From: Andrey Smetanin @ 2015-11-30 16:22 UTC (permalink / raw)
  To: kvm
  Cc: Gleb Natapov, Haiyang Zhang, qemu-devel, Roman Kagan,
	Denis V. Lunev, Paolo Bonzini, Vitaly Kuznetsov,
	K. Y. Srinivasan

The SynIC message protocol mandates that the message slot is claimed
by atomically setting message type to something other than HVMSG_NONE.
If another message is to be delivered while the slot is still busy,
message pending flag is asserted to indicate to the guest that the
hypervisor wants to be notified when the slot is released.

To make sure the protocol works regardless of where the message
sources are (kernel or userspace), clear the pending flag on SINT ACK
notification, and let the message sources compete for the slot again.

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: "K. Y. Srinivasan" <kys@microsoft.com>
CC: Haiyang Zhang <haiyangz@microsoft.com>
CC: Vitaly Kuznetsov <vkuznets@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    | 31 +++++++++++++++++++++++++++++++
 include/linux/kvm_host.h |  2 ++
 2 files changed, 33 insertions(+)

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index 9958926..6412b6b 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -27,6 +27,7 @@
 #include "hyperv.h"
 
 #include <linux/kvm_host.h>
+#include <linux/highmem.h>
 #include <asm/apicdef.h>
 #include <trace/events/kvm.h>
 
@@ -116,13 +117,43 @@ static struct kvm_vcpu_hv_synic *synic_get(struct kvm *kvm, u32 vcpu_id)
 	return (synic->active) ? synic : NULL;
 }
 
+static void synic_clear_sint_msg_pending(struct kvm_vcpu_hv_synic *synic,
+					u32 sint)
+{
+	struct kvm_vcpu *vcpu = synic_to_vcpu(synic);
+	struct page *page;
+	gpa_t gpa;
+	struct hv_message *msg;
+	struct hv_message_page *msg_page;
+
+	gpa = synic->msg_page & PAGE_MASK;
+	page = kvm_vcpu_gfn_to_page(vcpu, gpa >> PAGE_SHIFT);
+	if (is_error_page(page)) {
+		vcpu_err(vcpu, "Hyper-V SynIC can't get msg page, gpa 0x%llx\n",
+			 gpa);
+		return;
+	}
+	msg_page = kmap_atomic(page);
+
+	msg = &msg_page->sint_message[sint];
+	msg->header.message_flags.msg_pending = 0;
+
+	kunmap_atomic(msg_page);
+	kvm_release_page_dirty(page);
+	kvm_vcpu_mark_page_dirty(vcpu, gpa >> PAGE_SHIFT);
+}
+
 static void kvm_hv_notify_acked_sint(struct kvm_vcpu *vcpu, u32 sint)
 {
 	struct kvm *kvm = vcpu->kvm;
+	struct kvm_vcpu_hv_synic *synic = vcpu_to_synic(vcpu);
 	int gsi, idx;
 
 	vcpu_debug(vcpu, "Hyper-V SynIC acked sint %d\n", sint);
 
+	if (synic->msg_page & HV_SYNIC_SIMP_ENABLE)
+		synic_clear_sint_msg_pending(synic, sint);
+
 	idx = srcu_read_lock(&kvm->irq_srcu);
 	gsi = atomic_read(&vcpu_to_synic(vcpu)->sint_to_gsi[sint]);
 	if (gsi != -1)
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 2911919..9b64c8c 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -450,6 +450,8 @@ struct kvm {
 
 #define vcpu_debug(vcpu, fmt, ...)					\
 	kvm_debug("vcpu%i " fmt, (vcpu)->vcpu_id, ## __VA_ARGS__)
+#define vcpu_err(vcpu, fmt, ...)					\
+	kvm_err("vcpu%i " fmt, (vcpu)->vcpu_id, ## __VA_ARGS__)
 
 static inline struct kvm_vcpu *kvm_get_vcpu(struct kvm *kvm, int i)
 {
-- 
2.4.3

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

* [PATCH v2 9/9] kvm/x86: Hyper-V SynIC timers
  2015-11-30 16:22 ` [Qemu-devel] " Andrey Smetanin
@ 2015-11-30 16:22   ` Andrey Smetanin
  -1 siblings, 0 replies; 34+ messages in thread
From: Andrey Smetanin @ 2015-11-30 16:22 UTC (permalink / raw)
  To: kvm
  Cc: Gleb Natapov, Paolo Bonzini, K. Y. Srinivasan, Haiyang Zhang,
	Vitaly Kuznetsov, Roman Kagan, Denis V. Lunev, qemu-devel

Per Hyper-V specification (and as required by Hyper-V-aware guests),
SynIC provides 4 per-vCPU timers.  Each timer is programmed via a pair
of MSRs, and signals expiration by delivering a special format message
to the configured SynIC message slot and triggering the corresponding
synthetic interrupt.

Note: as implemented by this patch, all periodic timers are "lazy"
(i.e. if the vCPU wasn't scheduled for more than the timer period the
timer events are lost), regardless of the corresponding configuration
MSR.  If deemed necessary, the "catch up" mode (the timer period is
shortened until the timer catches up) will be implemented later.

Changes v2:
* Use remainder to calculate periodic timer expiration time

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: "K. Y. Srinivasan" <kys@microsoft.com>
CC: Haiyang Zhang <haiyangz@microsoft.com>
CC: Vitaly Kuznetsov <vkuznets@redhat.com>
CC: Roman Kagan <rkagan@virtuozzo.com>
CC: Denis V. Lunev <den@openvz.org>
CC: qemu-devel@nongnu.org
---
 arch/x86/include/asm/kvm_host.h    |  13 ++
 arch/x86/include/uapi/asm/hyperv.h |   6 +
 arch/x86/kvm/hyperv.c              | 318 ++++++++++++++++++++++++++++++++++++-
 arch/x86/kvm/hyperv.h              |  24 +++
 arch/x86/kvm/x86.c                 |   9 ++
 include/linux/kvm_host.h           |   1 +
 6 files changed, 368 insertions(+), 3 deletions(-)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 8140077..a7c8987 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -379,6 +379,17 @@ struct kvm_mtrr {
 	struct list_head head;
 };
 
+/* Hyper-V SynIC timer */
+struct kvm_vcpu_hv_stimer {
+	struct hrtimer timer;
+	int index;
+	u64 config;
+	u64 count;
+	u64 exp_time;
+	struct hv_message msg;
+	bool msg_pending;
+};
+
 /* Hyper-V synthetic interrupt controller (SynIC)*/
 struct kvm_vcpu_hv_synic {
 	u64 version;
@@ -398,6 +409,8 @@ struct kvm_vcpu_hv {
 	s64 runtime_offset;
 	struct kvm_vcpu_hv_synic synic;
 	struct kvm_hyperv_exit exit;
+	struct kvm_vcpu_hv_stimer stimer[HV_SYNIC_STIMER_COUNT];
+	DECLARE_BITMAP(stimer_pending_bitmap, HV_SYNIC_STIMER_COUNT);
 };
 
 struct kvm_vcpu_arch {
diff --git a/arch/x86/include/uapi/asm/hyperv.h b/arch/x86/include/uapi/asm/hyperv.h
index 42278f8..71fce3f 100644
--- a/arch/x86/include/uapi/asm/hyperv.h
+++ b/arch/x86/include/uapi/asm/hyperv.h
@@ -353,4 +353,10 @@ struct hv_timer_message_payload {
 	__u64 delivery_time;	/* When the message was delivered */
 };
 
+#define HV_STIMER_ENABLE		(1ULL << 0)
+#define HV_STIMER_PERIODIC		(1ULL << 1)
+#define HV_STIMER_LAZY			(1ULL << 2)
+#define HV_STIMER_AUTOENABLE		(1ULL << 3)
+#define HV_STIMER_SINT(config)		(__u8)(((config) >> 16) & 0x0F)
+
 #endif
diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index 6412b6b..8ff8829 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -147,15 +147,32 @@ static void kvm_hv_notify_acked_sint(struct kvm_vcpu *vcpu, u32 sint)
 {
 	struct kvm *kvm = vcpu->kvm;
 	struct kvm_vcpu_hv_synic *synic = vcpu_to_synic(vcpu);
-	int gsi, idx;
+	struct kvm_vcpu_hv *hv_vcpu = vcpu_to_hv_vcpu(vcpu);
+	struct kvm_vcpu_hv_stimer *stimer;
+	int gsi, idx, stimers_pending;
 
 	vcpu_debug(vcpu, "Hyper-V SynIC acked sint %d\n", sint);
 
 	if (synic->msg_page & HV_SYNIC_SIMP_ENABLE)
 		synic_clear_sint_msg_pending(synic, sint);
 
+	/* Try to deliver pending Hyper-V SynIC timers messages */
+	stimers_pending = 0;
+	for (idx = 0; idx < ARRAY_SIZE(hv_vcpu->stimer); idx++) {
+		stimer = &hv_vcpu->stimer[idx];
+		if (stimer->msg_pending &&
+		    (stimer->config & HV_STIMER_ENABLE) &&
+		    HV_STIMER_SINT(stimer->config) == sint) {
+			set_bit(stimer->index,
+				hv_vcpu->stimer_pending_bitmap);
+			stimers_pending++;
+		}
+	}
+	if (stimers_pending)
+		kvm_make_request(KVM_REQ_HV_STIMER, vcpu);
+
 	idx = srcu_read_lock(&kvm->irq_srcu);
-	gsi = atomic_read(&vcpu_to_synic(vcpu)->sint_to_gsi[sint]);
+	gsi = atomic_read(&synic->sint_to_gsi[sint]);
 	if (gsi != -1)
 		kvm_notify_acked_gsi(kvm, gsi);
 	srcu_read_unlock(&kvm->irq_srcu, idx);
@@ -371,9 +388,268 @@ 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,
+				bool vcpu_kick)
+{
+	struct kvm_vcpu *vcpu = stimer_to_vcpu(stimer);
+
+	set_bit(stimer->index,
+		vcpu_to_hv_vcpu(vcpu)->stimer_pending_bitmap);
+	kvm_make_request(KVM_REQ_HV_STIMER, vcpu);
+	if (vcpu_kick)
+		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);
+	clear_bit(stimer->index,
+		  vcpu_to_hv_vcpu(vcpu)->stimer_pending_bitmap);
+	stimer->msg_pending = false;
+}
+
+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);
+
+	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);
+}
+
+static int stimer_start(struct kvm_vcpu_hv_stimer *stimer)
+{
+	u64 time_now;
+	ktime_t ktime_now;
+
+	time_now = get_time_ref_counter(stimer_to_vcpu(stimer)->kvm);
+	ktime_now = ktime_get();
+
+	if (stimer->config & HV_STIMER_PERIODIC) {
+		if (stimer->count == 0)
+			return -EINVAL;
+
+		stimer->exp_time = time_now + stimer->count;
+		hrtimer_start(&stimer->timer,
+			      ktime_add_ns(ktime_now, 100 * stimer->count),
+			      HRTIMER_MODE_ABS);
+		return 0;
+	}
+	stimer->exp_time = stimer->count;
+	if (time_now >= stimer->count) {
+		/*
+		 * Expire timer according to Hypervisor Top-Level Functional
+		 * specification v4(15.3.1):
+		 * "If a one shot is enabled and the specified count is in
+		 * the past, it will expire immediately."
+		 */
+		stimer_mark_expired(stimer, false);
+		return 0;
+	}
+
+	hrtimer_start(&stimer->timer,
+		      ktime_add_ns(ktime_now, 100 * (stimer->count - time_now)),
+		      HRTIMER_MODE_ABS);
+	return 0;
+}
+
+static int stimer_set_config(struct kvm_vcpu_hv_stimer *stimer, u64 config,
+			     bool host)
+{
+	if (stimer->count == 0 || 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;
+	return 0;
+}
+
+static int stimer_set_count(struct kvm_vcpu_hv_stimer *stimer, u64 count,
+			    bool host)
+{
+	stimer->count = count;
+
+	stimer_cleanup(stimer);
+	if (stimer->count == 0)
+		stimer->config &= ~HV_STIMER_ENABLE;
+	else if (stimer->config & HV_STIMER_AUTOENABLE) {
+		stimer->config |= HV_STIMER_ENABLE;
+		if (stimer_start(stimer))
+			return 1;
+	}
+
+	return 0;
+}
+
+static int stimer_get_config(struct kvm_vcpu_hv_stimer *stimer, u64 *pconfig)
+{
+	*pconfig = stimer->config;
+	return 0;
+}
+
+static int stimer_get_count(struct kvm_vcpu_hv_stimer *stimer, u64 *pcount)
+{
+	*pcount = stimer->count;
+	return 0;
+}
+
+static int synic_deliver_msg(struct kvm_vcpu_hv_synic *synic, u32 sint,
+			     struct hv_message *src_msg)
+{
+	struct kvm_vcpu *vcpu = synic_to_vcpu(synic);
+	struct page *page;
+	gpa_t gpa;
+	struct hv_message *dst_msg;
+	int r;
+	struct hv_message_page *msg_page;
+
+	if (!(synic->msg_page & HV_SYNIC_SIMP_ENABLE))
+		return -ENOENT;
+
+	gpa = synic->msg_page & PAGE_MASK;
+	page = kvm_vcpu_gfn_to_page(vcpu, gpa >> PAGE_SHIFT);
+	if (is_error_page(page))
+		return -EFAULT;
+
+	msg_page = kmap_atomic(page);
+	dst_msg = &msg_page->sint_message[sint];
+	if (sync_cmpxchg(&dst_msg->header.message_type, HVMSG_NONE,
+			 src_msg->header.message_type) != HVMSG_NONE) {
+		dst_msg->header.message_flags.msg_pending = 1;
+		r = -EAGAIN;
+	} else {
+		memcpy(&dst_msg->u.payload, &src_msg->u.payload,
+		       src_msg->header.payload_size);
+		dst_msg->header.message_type = src_msg->header.message_type;
+		dst_msg->header.payload_size = src_msg->header.payload_size;
+		r = synic_set_irq(synic, sint);
+		if (r >= 1)
+			r = 0;
+		else if (r == 0)
+			r = -EFAULT;
+	}
+	kunmap_atomic(msg_page);
+	kvm_release_page_dirty(page);
+	kvm_vcpu_mark_page_dirty(vcpu, gpa >> PAGE_SHIFT);
+	return r;
+}
+
+static void 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;
+}
+
+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_restart(stimer);
+}
+
+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;
+	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];
+			stimer_stop(stimer);
+			if (stimer->config & HV_STIMER_ENABLE) {
+				time_now = get_time_ref_counter(vcpu->kvm);
+				if (time_now >= stimer->exp_time)
+					stimer_expiration(stimer);
+			}
+		}
+}
+
+void kvm_hv_vcpu_uninit(struct kvm_vcpu *vcpu)
+{
+	struct kvm_vcpu_hv *hv_vcpu = vcpu_to_hv_vcpu(vcpu);
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(hv_vcpu->stimer); i++)
+		stimer_cleanup(&hv_vcpu->stimer[i]);
+}
+
+static void stimer_prepare_msg(struct kvm_vcpu_hv_stimer *stimer)
+{
+	struct hv_message *msg = &stimer->msg;
+	struct hv_timer_message_payload *payload =
+			(struct hv_timer_message_payload *)&msg->u.payload;
+
+	memset(&msg->header, 0, sizeof(msg->header));
+	msg->header.message_type = HVMSG_TIMER_EXPIRED;
+	msg->header.payload_size = sizeof(*payload);
+
+	payload->timer_index = stimer->index;
+	payload->expiration_time = 0;
+	payload->delivery_time = 0;
+}
+
+static void stimer_init(struct kvm_vcpu_hv_stimer *stimer, int timer_index)
+{
+	memset(stimer, 0, sizeof(*stimer));
+	stimer->index = timer_index;
+	hrtimer_init(&stimer->timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
+	stimer->timer.function = stimer_timer_callback;
+	stimer_prepare_msg(stimer);
+}
+
 void kvm_hv_vcpu_init(struct kvm_vcpu *vcpu)
 {
-	synic_init(vcpu_to_synic(vcpu));
+	struct kvm_vcpu_hv *hv_vcpu = vcpu_to_hv_vcpu(vcpu);
+	int i;
+
+	synic_init(&hv_vcpu->synic);
+
+	bitmap_zero(hv_vcpu->stimer_pending_bitmap, HV_SYNIC_STIMER_COUNT);
+	for (i = 0; i < ARRAY_SIZE(hv_vcpu->stimer); i++)
+		stimer_init(&hv_vcpu->stimer[i], i);
 }
 
 int kvm_hv_activate_synic(struct kvm_vcpu *vcpu)
@@ -590,6 +866,24 @@ static int kvm_hv_set_msr(struct kvm_vcpu *vcpu, u32 msr, u64 data, bool host)
 	case HV_X64_MSR_EOM:
 	case HV_X64_MSR_SINT0 ... HV_X64_MSR_SINT15:
 		return synic_set_msr(vcpu_to_synic(vcpu), msr, data, host);
+	case HV_X64_MSR_STIMER0_CONFIG:
+	case HV_X64_MSR_STIMER1_CONFIG:
+	case HV_X64_MSR_STIMER2_CONFIG:
+	case HV_X64_MSR_STIMER3_CONFIG: {
+		int timer_index = (msr - HV_X64_MSR_STIMER0_CONFIG)/2;
+
+		return stimer_set_config(vcpu_to_stimer(vcpu, timer_index),
+					 data, host);
+	}
+	case HV_X64_MSR_STIMER0_COUNT:
+	case HV_X64_MSR_STIMER1_COUNT:
+	case HV_X64_MSR_STIMER2_COUNT:
+	case HV_X64_MSR_STIMER3_COUNT: {
+		int timer_index = (msr - HV_X64_MSR_STIMER0_COUNT)/2;
+
+		return stimer_set_count(vcpu_to_stimer(vcpu, timer_index),
+					data, host);
+	}
 	default:
 		vcpu_unimpl(vcpu, "Hyper-V uhandled wrmsr: 0x%x data 0x%llx\n",
 			    msr, data);
@@ -673,6 +967,24 @@ static int kvm_hv_get_msr(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
 	case HV_X64_MSR_EOM:
 	case HV_X64_MSR_SINT0 ... HV_X64_MSR_SINT15:
 		return synic_get_msr(vcpu_to_synic(vcpu), msr, pdata);
+	case HV_X64_MSR_STIMER0_CONFIG:
+	case HV_X64_MSR_STIMER1_CONFIG:
+	case HV_X64_MSR_STIMER2_CONFIG:
+	case HV_X64_MSR_STIMER3_CONFIG: {
+		int timer_index = (msr - HV_X64_MSR_STIMER0_CONFIG)/2;
+
+		return stimer_get_config(vcpu_to_stimer(vcpu, timer_index),
+					 pdata);
+	}
+	case HV_X64_MSR_STIMER0_COUNT:
+	case HV_X64_MSR_STIMER1_COUNT:
+	case HV_X64_MSR_STIMER2_COUNT:
+	case HV_X64_MSR_STIMER3_COUNT: {
+		int timer_index = (msr - HV_X64_MSR_STIMER0_COUNT)/2;
+
+		return stimer_get_count(vcpu_to_stimer(vcpu, timer_index),
+					pdata);
+	}
 	default:
 		vcpu_unimpl(vcpu, "Hyper-V unhandled rdmsr: 0x%x\n", msr);
 		return 1;
diff --git a/arch/x86/kvm/hyperv.h b/arch/x86/kvm/hyperv.h
index d5d8217..60eccd4 100644
--- a/arch/x86/kvm/hyperv.h
+++ b/arch/x86/kvm/hyperv.h
@@ -59,5 +59,29 @@ void kvm_hv_synic_send_eoi(struct kvm_vcpu *vcpu, int vector);
 int kvm_hv_activate_synic(struct kvm_vcpu *vcpu);
 
 void kvm_hv_vcpu_init(struct kvm_vcpu *vcpu);
+void kvm_hv_vcpu_uninit(struct kvm_vcpu *vcpu);
+
+static inline struct kvm_vcpu_hv_stimer *vcpu_to_stimer(struct kvm_vcpu *vcpu,
+							int timer_index)
+{
+	return &vcpu_to_hv_vcpu(vcpu)->stimer[timer_index];
+}
+
+static inline struct kvm_vcpu *stimer_to_vcpu(struct kvm_vcpu_hv_stimer *stimer)
+{
+	struct kvm_vcpu_hv *hv_vcpu;
+
+	hv_vcpu = container_of(stimer - stimer->index, struct kvm_vcpu_hv,
+			       stimer[0]);
+	return hv_vcpu_to_vcpu(hv_vcpu);
+}
+
+static inline bool kvm_hv_has_stimer_pending(struct kvm_vcpu *vcpu)
+{
+	return !bitmap_empty(vcpu->arch.hyperv.stimer_pending_bitmap,
+			     HV_SYNIC_STIMER_COUNT);
+}
+
+void kvm_hv_process_stimers(struct kvm_vcpu *vcpu);
 
 #endif
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index f1d6501..b6102c1 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -967,6 +967,7 @@ static u32 emulated_msrs[] = {
 	HV_X64_MSR_VP_INDEX,
 	HV_X64_MSR_VP_RUNTIME,
 	HV_X64_MSR_SCONTROL,
+	HV_X64_MSR_STIMER0_CONFIG,
 	HV_X64_MSR_APIC_ASSIST_PAGE, MSR_KVM_ASYNC_PF_EN, MSR_KVM_STEAL_TIME,
 	MSR_KVM_PV_EOI_EN,
 
@@ -2199,6 +2200,7 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
 	case HV_X64_MSR_GUEST_OS_ID ... HV_X64_MSR_SINT15:
 	case HV_X64_MSR_CRASH_P0 ... HV_X64_MSR_CRASH_P4:
 	case HV_X64_MSR_CRASH_CTL:
+	case HV_X64_MSR_STIMER0_CONFIG ... HV_X64_MSR_STIMER3_COUNT:
 		return kvm_hv_set_msr_common(vcpu, msr, data,
 					     msr_info->host_initiated);
 	case MSR_IA32_BBL_CR_CTL3:
@@ -2403,6 +2405,7 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
 	case HV_X64_MSR_GUEST_OS_ID ... HV_X64_MSR_SINT15:
 	case HV_X64_MSR_CRASH_P0 ... HV_X64_MSR_CRASH_P4:
 	case HV_X64_MSR_CRASH_CTL:
+	case HV_X64_MSR_STIMER0_CONFIG ... HV_X64_MSR_STIMER3_COUNT:
 		return kvm_hv_get_msr_common(vcpu,
 					     msr_info->index, &msr_info->data);
 		break;
@@ -6489,6 +6492,8 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
 			r = 0;
 			goto out;
 		}
+		if (kvm_check_request(KVM_REQ_HV_STIMER, vcpu))
+			kvm_hv_process_stimers(vcpu);
 	}
 
 	/*
@@ -7649,6 +7654,7 @@ void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu)
 {
 	int idx;
 
+	kvm_hv_vcpu_uninit(vcpu);
 	kvm_pmu_destroy(vcpu);
 	kfree(vcpu->arch.mce_banks);
 	kvm_free_lapic(vcpu);
@@ -8043,6 +8049,9 @@ static inline bool kvm_vcpu_has_events(struct kvm_vcpu *vcpu)
 	    kvm_cpu_has_interrupt(vcpu))
 		return true;
 
+	if (kvm_hv_has_stimer_pending(vcpu))
+		return true;
+
 	return false;
 }
 
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 9b64c8c..57a7ce8 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -144,6 +144,7 @@ static inline bool is_error_page(struct page *page)
 #define KVM_REQ_IOAPIC_EOI_EXIT   28
 #define KVM_REQ_HV_RESET          29
 #define KVM_REQ_HV_EXIT           30
+#define KVM_REQ_HV_STIMER         31
 
 #define KVM_USERSPACE_IRQ_SOURCE_ID		0
 #define KVM_IRQFD_RESAMPLE_IRQ_SOURCE_ID	1
-- 
2.4.3


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

* [Qemu-devel] [PATCH v2 9/9] kvm/x86: Hyper-V SynIC timers
@ 2015-11-30 16:22   ` Andrey Smetanin
  0 siblings, 0 replies; 34+ messages in thread
From: Andrey Smetanin @ 2015-11-30 16:22 UTC (permalink / raw)
  To: kvm
  Cc: Gleb Natapov, Haiyang Zhang, qemu-devel, Roman Kagan,
	Denis V. Lunev, Paolo Bonzini, Vitaly Kuznetsov,
	K. Y. Srinivasan

Per Hyper-V specification (and as required by Hyper-V-aware guests),
SynIC provides 4 per-vCPU timers.  Each timer is programmed via a pair
of MSRs, and signals expiration by delivering a special format message
to the configured SynIC message slot and triggering the corresponding
synthetic interrupt.

Note: as implemented by this patch, all periodic timers are "lazy"
(i.e. if the vCPU wasn't scheduled for more than the timer period the
timer events are lost), regardless of the corresponding configuration
MSR.  If deemed necessary, the "catch up" mode (the timer period is
shortened until the timer catches up) will be implemented later.

Changes v2:
* Use remainder to calculate periodic timer expiration time

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: "K. Y. Srinivasan" <kys@microsoft.com>
CC: Haiyang Zhang <haiyangz@microsoft.com>
CC: Vitaly Kuznetsov <vkuznets@redhat.com>
CC: Roman Kagan <rkagan@virtuozzo.com>
CC: Denis V. Lunev <den@openvz.org>
CC: qemu-devel@nongnu.org
---
 arch/x86/include/asm/kvm_host.h    |  13 ++
 arch/x86/include/uapi/asm/hyperv.h |   6 +
 arch/x86/kvm/hyperv.c              | 318 ++++++++++++++++++++++++++++++++++++-
 arch/x86/kvm/hyperv.h              |  24 +++
 arch/x86/kvm/x86.c                 |   9 ++
 include/linux/kvm_host.h           |   1 +
 6 files changed, 368 insertions(+), 3 deletions(-)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 8140077..a7c8987 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -379,6 +379,17 @@ struct kvm_mtrr {
 	struct list_head head;
 };
 
+/* Hyper-V SynIC timer */
+struct kvm_vcpu_hv_stimer {
+	struct hrtimer timer;
+	int index;
+	u64 config;
+	u64 count;
+	u64 exp_time;
+	struct hv_message msg;
+	bool msg_pending;
+};
+
 /* Hyper-V synthetic interrupt controller (SynIC)*/
 struct kvm_vcpu_hv_synic {
 	u64 version;
@@ -398,6 +409,8 @@ struct kvm_vcpu_hv {
 	s64 runtime_offset;
 	struct kvm_vcpu_hv_synic synic;
 	struct kvm_hyperv_exit exit;
+	struct kvm_vcpu_hv_stimer stimer[HV_SYNIC_STIMER_COUNT];
+	DECLARE_BITMAP(stimer_pending_bitmap, HV_SYNIC_STIMER_COUNT);
 };
 
 struct kvm_vcpu_arch {
diff --git a/arch/x86/include/uapi/asm/hyperv.h b/arch/x86/include/uapi/asm/hyperv.h
index 42278f8..71fce3f 100644
--- a/arch/x86/include/uapi/asm/hyperv.h
+++ b/arch/x86/include/uapi/asm/hyperv.h
@@ -353,4 +353,10 @@ struct hv_timer_message_payload {
 	__u64 delivery_time;	/* When the message was delivered */
 };
 
+#define HV_STIMER_ENABLE		(1ULL << 0)
+#define HV_STIMER_PERIODIC		(1ULL << 1)
+#define HV_STIMER_LAZY			(1ULL << 2)
+#define HV_STIMER_AUTOENABLE		(1ULL << 3)
+#define HV_STIMER_SINT(config)		(__u8)(((config) >> 16) & 0x0F)
+
 #endif
diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index 6412b6b..8ff8829 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -147,15 +147,32 @@ static void kvm_hv_notify_acked_sint(struct kvm_vcpu *vcpu, u32 sint)
 {
 	struct kvm *kvm = vcpu->kvm;
 	struct kvm_vcpu_hv_synic *synic = vcpu_to_synic(vcpu);
-	int gsi, idx;
+	struct kvm_vcpu_hv *hv_vcpu = vcpu_to_hv_vcpu(vcpu);
+	struct kvm_vcpu_hv_stimer *stimer;
+	int gsi, idx, stimers_pending;
 
 	vcpu_debug(vcpu, "Hyper-V SynIC acked sint %d\n", sint);
 
 	if (synic->msg_page & HV_SYNIC_SIMP_ENABLE)
 		synic_clear_sint_msg_pending(synic, sint);
 
+	/* Try to deliver pending Hyper-V SynIC timers messages */
+	stimers_pending = 0;
+	for (idx = 0; idx < ARRAY_SIZE(hv_vcpu->stimer); idx++) {
+		stimer = &hv_vcpu->stimer[idx];
+		if (stimer->msg_pending &&
+		    (stimer->config & HV_STIMER_ENABLE) &&
+		    HV_STIMER_SINT(stimer->config) == sint) {
+			set_bit(stimer->index,
+				hv_vcpu->stimer_pending_bitmap);
+			stimers_pending++;
+		}
+	}
+	if (stimers_pending)
+		kvm_make_request(KVM_REQ_HV_STIMER, vcpu);
+
 	idx = srcu_read_lock(&kvm->irq_srcu);
-	gsi = atomic_read(&vcpu_to_synic(vcpu)->sint_to_gsi[sint]);
+	gsi = atomic_read(&synic->sint_to_gsi[sint]);
 	if (gsi != -1)
 		kvm_notify_acked_gsi(kvm, gsi);
 	srcu_read_unlock(&kvm->irq_srcu, idx);
@@ -371,9 +388,268 @@ 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,
+				bool vcpu_kick)
+{
+	struct kvm_vcpu *vcpu = stimer_to_vcpu(stimer);
+
+	set_bit(stimer->index,
+		vcpu_to_hv_vcpu(vcpu)->stimer_pending_bitmap);
+	kvm_make_request(KVM_REQ_HV_STIMER, vcpu);
+	if (vcpu_kick)
+		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);
+	clear_bit(stimer->index,
+		  vcpu_to_hv_vcpu(vcpu)->stimer_pending_bitmap);
+	stimer->msg_pending = false;
+}
+
+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);
+
+	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);
+}
+
+static int stimer_start(struct kvm_vcpu_hv_stimer *stimer)
+{
+	u64 time_now;
+	ktime_t ktime_now;
+
+	time_now = get_time_ref_counter(stimer_to_vcpu(stimer)->kvm);
+	ktime_now = ktime_get();
+
+	if (stimer->config & HV_STIMER_PERIODIC) {
+		if (stimer->count == 0)
+			return -EINVAL;
+
+		stimer->exp_time = time_now + stimer->count;
+		hrtimer_start(&stimer->timer,
+			      ktime_add_ns(ktime_now, 100 * stimer->count),
+			      HRTIMER_MODE_ABS);
+		return 0;
+	}
+	stimer->exp_time = stimer->count;
+	if (time_now >= stimer->count) {
+		/*
+		 * Expire timer according to Hypervisor Top-Level Functional
+		 * specification v4(15.3.1):
+		 * "If a one shot is enabled and the specified count is in
+		 * the past, it will expire immediately."
+		 */
+		stimer_mark_expired(stimer, false);
+		return 0;
+	}
+
+	hrtimer_start(&stimer->timer,
+		      ktime_add_ns(ktime_now, 100 * (stimer->count - time_now)),
+		      HRTIMER_MODE_ABS);
+	return 0;
+}
+
+static int stimer_set_config(struct kvm_vcpu_hv_stimer *stimer, u64 config,
+			     bool host)
+{
+	if (stimer->count == 0 || 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;
+	return 0;
+}
+
+static int stimer_set_count(struct kvm_vcpu_hv_stimer *stimer, u64 count,
+			    bool host)
+{
+	stimer->count = count;
+
+	stimer_cleanup(stimer);
+	if (stimer->count == 0)
+		stimer->config &= ~HV_STIMER_ENABLE;
+	else if (stimer->config & HV_STIMER_AUTOENABLE) {
+		stimer->config |= HV_STIMER_ENABLE;
+		if (stimer_start(stimer))
+			return 1;
+	}
+
+	return 0;
+}
+
+static int stimer_get_config(struct kvm_vcpu_hv_stimer *stimer, u64 *pconfig)
+{
+	*pconfig = stimer->config;
+	return 0;
+}
+
+static int stimer_get_count(struct kvm_vcpu_hv_stimer *stimer, u64 *pcount)
+{
+	*pcount = stimer->count;
+	return 0;
+}
+
+static int synic_deliver_msg(struct kvm_vcpu_hv_synic *synic, u32 sint,
+			     struct hv_message *src_msg)
+{
+	struct kvm_vcpu *vcpu = synic_to_vcpu(synic);
+	struct page *page;
+	gpa_t gpa;
+	struct hv_message *dst_msg;
+	int r;
+	struct hv_message_page *msg_page;
+
+	if (!(synic->msg_page & HV_SYNIC_SIMP_ENABLE))
+		return -ENOENT;
+
+	gpa = synic->msg_page & PAGE_MASK;
+	page = kvm_vcpu_gfn_to_page(vcpu, gpa >> PAGE_SHIFT);
+	if (is_error_page(page))
+		return -EFAULT;
+
+	msg_page = kmap_atomic(page);
+	dst_msg = &msg_page->sint_message[sint];
+	if (sync_cmpxchg(&dst_msg->header.message_type, HVMSG_NONE,
+			 src_msg->header.message_type) != HVMSG_NONE) {
+		dst_msg->header.message_flags.msg_pending = 1;
+		r = -EAGAIN;
+	} else {
+		memcpy(&dst_msg->u.payload, &src_msg->u.payload,
+		       src_msg->header.payload_size);
+		dst_msg->header.message_type = src_msg->header.message_type;
+		dst_msg->header.payload_size = src_msg->header.payload_size;
+		r = synic_set_irq(synic, sint);
+		if (r >= 1)
+			r = 0;
+		else if (r == 0)
+			r = -EFAULT;
+	}
+	kunmap_atomic(msg_page);
+	kvm_release_page_dirty(page);
+	kvm_vcpu_mark_page_dirty(vcpu, gpa >> PAGE_SHIFT);
+	return r;
+}
+
+static void 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;
+}
+
+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_restart(stimer);
+}
+
+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;
+	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];
+			stimer_stop(stimer);
+			if (stimer->config & HV_STIMER_ENABLE) {
+				time_now = get_time_ref_counter(vcpu->kvm);
+				if (time_now >= stimer->exp_time)
+					stimer_expiration(stimer);
+			}
+		}
+}
+
+void kvm_hv_vcpu_uninit(struct kvm_vcpu *vcpu)
+{
+	struct kvm_vcpu_hv *hv_vcpu = vcpu_to_hv_vcpu(vcpu);
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(hv_vcpu->stimer); i++)
+		stimer_cleanup(&hv_vcpu->stimer[i]);
+}
+
+static void stimer_prepare_msg(struct kvm_vcpu_hv_stimer *stimer)
+{
+	struct hv_message *msg = &stimer->msg;
+	struct hv_timer_message_payload *payload =
+			(struct hv_timer_message_payload *)&msg->u.payload;
+
+	memset(&msg->header, 0, sizeof(msg->header));
+	msg->header.message_type = HVMSG_TIMER_EXPIRED;
+	msg->header.payload_size = sizeof(*payload);
+
+	payload->timer_index = stimer->index;
+	payload->expiration_time = 0;
+	payload->delivery_time = 0;
+}
+
+static void stimer_init(struct kvm_vcpu_hv_stimer *stimer, int timer_index)
+{
+	memset(stimer, 0, sizeof(*stimer));
+	stimer->index = timer_index;
+	hrtimer_init(&stimer->timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
+	stimer->timer.function = stimer_timer_callback;
+	stimer_prepare_msg(stimer);
+}
+
 void kvm_hv_vcpu_init(struct kvm_vcpu *vcpu)
 {
-	synic_init(vcpu_to_synic(vcpu));
+	struct kvm_vcpu_hv *hv_vcpu = vcpu_to_hv_vcpu(vcpu);
+	int i;
+
+	synic_init(&hv_vcpu->synic);
+
+	bitmap_zero(hv_vcpu->stimer_pending_bitmap, HV_SYNIC_STIMER_COUNT);
+	for (i = 0; i < ARRAY_SIZE(hv_vcpu->stimer); i++)
+		stimer_init(&hv_vcpu->stimer[i], i);
 }
 
 int kvm_hv_activate_synic(struct kvm_vcpu *vcpu)
@@ -590,6 +866,24 @@ static int kvm_hv_set_msr(struct kvm_vcpu *vcpu, u32 msr, u64 data, bool host)
 	case HV_X64_MSR_EOM:
 	case HV_X64_MSR_SINT0 ... HV_X64_MSR_SINT15:
 		return synic_set_msr(vcpu_to_synic(vcpu), msr, data, host);
+	case HV_X64_MSR_STIMER0_CONFIG:
+	case HV_X64_MSR_STIMER1_CONFIG:
+	case HV_X64_MSR_STIMER2_CONFIG:
+	case HV_X64_MSR_STIMER3_CONFIG: {
+		int timer_index = (msr - HV_X64_MSR_STIMER0_CONFIG)/2;
+
+		return stimer_set_config(vcpu_to_stimer(vcpu, timer_index),
+					 data, host);
+	}
+	case HV_X64_MSR_STIMER0_COUNT:
+	case HV_X64_MSR_STIMER1_COUNT:
+	case HV_X64_MSR_STIMER2_COUNT:
+	case HV_X64_MSR_STIMER3_COUNT: {
+		int timer_index = (msr - HV_X64_MSR_STIMER0_COUNT)/2;
+
+		return stimer_set_count(vcpu_to_stimer(vcpu, timer_index),
+					data, host);
+	}
 	default:
 		vcpu_unimpl(vcpu, "Hyper-V uhandled wrmsr: 0x%x data 0x%llx\n",
 			    msr, data);
@@ -673,6 +967,24 @@ static int kvm_hv_get_msr(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
 	case HV_X64_MSR_EOM:
 	case HV_X64_MSR_SINT0 ... HV_X64_MSR_SINT15:
 		return synic_get_msr(vcpu_to_synic(vcpu), msr, pdata);
+	case HV_X64_MSR_STIMER0_CONFIG:
+	case HV_X64_MSR_STIMER1_CONFIG:
+	case HV_X64_MSR_STIMER2_CONFIG:
+	case HV_X64_MSR_STIMER3_CONFIG: {
+		int timer_index = (msr - HV_X64_MSR_STIMER0_CONFIG)/2;
+
+		return stimer_get_config(vcpu_to_stimer(vcpu, timer_index),
+					 pdata);
+	}
+	case HV_X64_MSR_STIMER0_COUNT:
+	case HV_X64_MSR_STIMER1_COUNT:
+	case HV_X64_MSR_STIMER2_COUNT:
+	case HV_X64_MSR_STIMER3_COUNT: {
+		int timer_index = (msr - HV_X64_MSR_STIMER0_COUNT)/2;
+
+		return stimer_get_count(vcpu_to_stimer(vcpu, timer_index),
+					pdata);
+	}
 	default:
 		vcpu_unimpl(vcpu, "Hyper-V unhandled rdmsr: 0x%x\n", msr);
 		return 1;
diff --git a/arch/x86/kvm/hyperv.h b/arch/x86/kvm/hyperv.h
index d5d8217..60eccd4 100644
--- a/arch/x86/kvm/hyperv.h
+++ b/arch/x86/kvm/hyperv.h
@@ -59,5 +59,29 @@ void kvm_hv_synic_send_eoi(struct kvm_vcpu *vcpu, int vector);
 int kvm_hv_activate_synic(struct kvm_vcpu *vcpu);
 
 void kvm_hv_vcpu_init(struct kvm_vcpu *vcpu);
+void kvm_hv_vcpu_uninit(struct kvm_vcpu *vcpu);
+
+static inline struct kvm_vcpu_hv_stimer *vcpu_to_stimer(struct kvm_vcpu *vcpu,
+							int timer_index)
+{
+	return &vcpu_to_hv_vcpu(vcpu)->stimer[timer_index];
+}
+
+static inline struct kvm_vcpu *stimer_to_vcpu(struct kvm_vcpu_hv_stimer *stimer)
+{
+	struct kvm_vcpu_hv *hv_vcpu;
+
+	hv_vcpu = container_of(stimer - stimer->index, struct kvm_vcpu_hv,
+			       stimer[0]);
+	return hv_vcpu_to_vcpu(hv_vcpu);
+}
+
+static inline bool kvm_hv_has_stimer_pending(struct kvm_vcpu *vcpu)
+{
+	return !bitmap_empty(vcpu->arch.hyperv.stimer_pending_bitmap,
+			     HV_SYNIC_STIMER_COUNT);
+}
+
+void kvm_hv_process_stimers(struct kvm_vcpu *vcpu);
 
 #endif
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index f1d6501..b6102c1 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -967,6 +967,7 @@ static u32 emulated_msrs[] = {
 	HV_X64_MSR_VP_INDEX,
 	HV_X64_MSR_VP_RUNTIME,
 	HV_X64_MSR_SCONTROL,
+	HV_X64_MSR_STIMER0_CONFIG,
 	HV_X64_MSR_APIC_ASSIST_PAGE, MSR_KVM_ASYNC_PF_EN, MSR_KVM_STEAL_TIME,
 	MSR_KVM_PV_EOI_EN,
 
@@ -2199,6 +2200,7 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
 	case HV_X64_MSR_GUEST_OS_ID ... HV_X64_MSR_SINT15:
 	case HV_X64_MSR_CRASH_P0 ... HV_X64_MSR_CRASH_P4:
 	case HV_X64_MSR_CRASH_CTL:
+	case HV_X64_MSR_STIMER0_CONFIG ... HV_X64_MSR_STIMER3_COUNT:
 		return kvm_hv_set_msr_common(vcpu, msr, data,
 					     msr_info->host_initiated);
 	case MSR_IA32_BBL_CR_CTL3:
@@ -2403,6 +2405,7 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
 	case HV_X64_MSR_GUEST_OS_ID ... HV_X64_MSR_SINT15:
 	case HV_X64_MSR_CRASH_P0 ... HV_X64_MSR_CRASH_P4:
 	case HV_X64_MSR_CRASH_CTL:
+	case HV_X64_MSR_STIMER0_CONFIG ... HV_X64_MSR_STIMER3_COUNT:
 		return kvm_hv_get_msr_common(vcpu,
 					     msr_info->index, &msr_info->data);
 		break;
@@ -6489,6 +6492,8 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
 			r = 0;
 			goto out;
 		}
+		if (kvm_check_request(KVM_REQ_HV_STIMER, vcpu))
+			kvm_hv_process_stimers(vcpu);
 	}
 
 	/*
@@ -7649,6 +7654,7 @@ void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu)
 {
 	int idx;
 
+	kvm_hv_vcpu_uninit(vcpu);
 	kvm_pmu_destroy(vcpu);
 	kfree(vcpu->arch.mce_banks);
 	kvm_free_lapic(vcpu);
@@ -8043,6 +8049,9 @@ static inline bool kvm_vcpu_has_events(struct kvm_vcpu *vcpu)
 	    kvm_cpu_has_interrupt(vcpu))
 		return true;
 
+	if (kvm_hv_has_stimer_pending(vcpu))
+		return true;
+
 	return false;
 }
 
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 9b64c8c..57a7ce8 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -144,6 +144,7 @@ static inline bool is_error_page(struct page *page)
 #define KVM_REQ_IOAPIC_EOI_EXIT   28
 #define KVM_REQ_HV_RESET          29
 #define KVM_REQ_HV_EXIT           30
+#define KVM_REQ_HV_STIMER         31
 
 #define KVM_USERSPACE_IRQ_SOURCE_ID		0
 #define KVM_IRQFD_RESAMPLE_IRQ_SOURCE_ID	1
-- 
2.4.3

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

* Re: [PATCH v2 1/9] drivers/hv: replace enum hv_message_type by u32
  2015-11-30 16:22   ` [Qemu-devel] " Andrey Smetanin
@ 2015-12-02 12:22     ` Paolo Bonzini
  -1 siblings, 0 replies; 34+ messages in thread
From: Paolo Bonzini @ 2015-12-02 12:22 UTC (permalink / raw)
  To: Andrey Smetanin, kvm
  Cc: Gleb Natapov, K. Y. Srinivasan, Haiyang Zhang, Vitaly Kuznetsov,
	Roman Kagan, Denis V. Lunev, qemu-devel



On 30/11/2015 17:22, Andrey Smetanin wrote:
> enum hv_message_type inside struct hv_message, hv_post_message
> is not size portable. Replace enum by u32.

It's only non-portable inside structs.  Okay to apply just these:

@@ -172,7 +174,7 @@ union hv_message_flags {

 /* Define synthetic interrupt controller message header. */
 struct hv_message_header {
-	u32 message_type;
+	enum hv_message_type message_type;
 	u8 payload_size;
 	union hv_message_flags message_flags;
 	u8 reserved[2];
@@ -345,7 +347,7 @@ enum hv_call_code {
 struct hv_input_post_message {
 	union hv_connection_id connectionid;
 	u32 reserved;
-	u32 message_type;
+	enum hv_message_type message_type;
 	u32 payload_size;
 	u64 payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
 };

?

Paolo

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

* Re: [Qemu-devel] [PATCH v2 1/9] drivers/hv: replace enum hv_message_type by u32
@ 2015-12-02 12:22     ` Paolo Bonzini
  0 siblings, 0 replies; 34+ messages in thread
From: Paolo Bonzini @ 2015-12-02 12:22 UTC (permalink / raw)
  To: Andrey Smetanin, kvm
  Cc: Gleb Natapov, Haiyang Zhang, qemu-devel, Roman Kagan,
	Denis V. Lunev, Vitaly Kuznetsov, K. Y. Srinivasan



On 30/11/2015 17:22, Andrey Smetanin wrote:
> enum hv_message_type inside struct hv_message, hv_post_message
> is not size portable. Replace enum by u32.

It's only non-portable inside structs.  Okay to apply just these:

@@ -172,7 +174,7 @@ union hv_message_flags {

 /* Define synthetic interrupt controller message header. */
 struct hv_message_header {
-	u32 message_type;
+	enum hv_message_type message_type;
 	u8 payload_size;
 	union hv_message_flags message_flags;
 	u8 reserved[2];
@@ -345,7 +347,7 @@ enum hv_call_code {
 struct hv_input_post_message {
 	union hv_connection_id connectionid;
 	u32 reserved;
-	u32 message_type;
+	enum hv_message_type message_type;
 	u32 payload_size;
 	u64 payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
 };

?

Paolo

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

* Re: [PATCH v2 1/9] drivers/hv: replace enum hv_message_type by u32
  2015-12-02 12:22     ` [Qemu-devel] " Paolo Bonzini
@ 2015-12-04 14:33       ` Denis V. Lunev
  -1 siblings, 0 replies; 34+ messages in thread
From: Denis V. Lunev @ 2015-12-04 14:33 UTC (permalink / raw)
  To: Paolo Bonzini, Andrey Smetanin, kvm, Vitaly Kuznetsov
  Cc: Gleb Natapov, Haiyang Zhang, K. Y. Srinivasan, Roman Kagan, qemu-devel

On 12/02/2015 03:22 PM, Paolo Bonzini wrote:
>
> On 30/11/2015 17:22, Andrey Smetanin wrote:
>> enum hv_message_type inside struct hv_message, hv_post_message
>> is not size portable. Replace enum by u32.
> It's only non-portable inside structs.  Okay to apply just these:
>
> @@ -172,7 +174,7 @@ union hv_message_flags {
>
>   /* Define synthetic interrupt controller message header. */
>   struct hv_message_header {
> -	u32 message_type;
> +	enum hv_message_type message_type;
>   	u8 payload_size;
>   	union hv_message_flags message_flags;
>   	u8 reserved[2];
> @@ -345,7 +347,7 @@ enum hv_call_code {
>   struct hv_input_post_message {
>   	union hv_connection_id connectionid;
>   	u32 reserved;
> -	u32 message_type;
> +	enum hv_message_type message_type;
>   	u32 payload_size;
>   	u64 payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
>   };
>
> ?
>
> Paolo
sorry for the delay.

Andrey is on vacation till the end of the week.

This could be not enough for some compilers as this exact
enum could be signed and unsigned depends upon the
implementation of the compiler and if it is signed we
can face signed/unsigned comparison in ifs.

Vitaly, by the way, this code is a bit rotten. The only caller of
hv_post_message calls it with message type exactly written
as "1", which is not defined in the enum.

/*
  * vmbus_post_msg - Send a msg on the vmbus's message connection
  */
int vmbus_post_msg(void *buffer, size_t buflen)
{
     ...
     ret = hv_post_message(conn_id, 1, buffer, buflen);

Den

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

* Re: [Qemu-devel] [PATCH v2 1/9] drivers/hv: replace enum hv_message_type by u32
@ 2015-12-04 14:33       ` Denis V. Lunev
  0 siblings, 0 replies; 34+ messages in thread
From: Denis V. Lunev @ 2015-12-04 14:33 UTC (permalink / raw)
  To: Paolo Bonzini, Andrey Smetanin, kvm, Vitaly Kuznetsov
  Cc: Gleb Natapov, Haiyang Zhang, K. Y. Srinivasan, Roman Kagan, qemu-devel

On 12/02/2015 03:22 PM, Paolo Bonzini wrote:
>
> On 30/11/2015 17:22, Andrey Smetanin wrote:
>> enum hv_message_type inside struct hv_message, hv_post_message
>> is not size portable. Replace enum by u32.
> It's only non-portable inside structs.  Okay to apply just these:
>
> @@ -172,7 +174,7 @@ union hv_message_flags {
>
>   /* Define synthetic interrupt controller message header. */
>   struct hv_message_header {
> -	u32 message_type;
> +	enum hv_message_type message_type;
>   	u8 payload_size;
>   	union hv_message_flags message_flags;
>   	u8 reserved[2];
> @@ -345,7 +347,7 @@ enum hv_call_code {
>   struct hv_input_post_message {
>   	union hv_connection_id connectionid;
>   	u32 reserved;
> -	u32 message_type;
> +	enum hv_message_type message_type;
>   	u32 payload_size;
>   	u64 payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
>   };
>
> ?
>
> Paolo
sorry for the delay.

Andrey is on vacation till the end of the week.

This could be not enough for some compilers as this exact
enum could be signed and unsigned depends upon the
implementation of the compiler and if it is signed we
can face signed/unsigned comparison in ifs.

Vitaly, by the way, this code is a bit rotten. The only caller of
hv_post_message calls it with message type exactly written
as "1", which is not defined in the enum.

/*
  * vmbus_post_msg - Send a msg on the vmbus's message connection
  */
int vmbus_post_msg(void *buffer, size_t buflen)
{
     ...
     ret = hv_post_message(conn_id, 1, buffer, buflen);

Den

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

* Re: [PATCH v2 1/9] drivers/hv: replace enum hv_message_type by u32
  2015-12-04 14:33       ` [Qemu-devel] " Denis V. Lunev
@ 2015-12-04 14:41         ` Paolo Bonzini
  -1 siblings, 0 replies; 34+ messages in thread
From: Paolo Bonzini @ 2015-12-04 14:41 UTC (permalink / raw)
  To: Denis V. Lunev, Andrey Smetanin, kvm, Vitaly Kuznetsov
  Cc: Gleb Natapov, K. Y. Srinivasan, Haiyang Zhang, Roman Kagan, qemu-devel



On 04/12/2015 15:33, Denis V. Lunev wrote:
> On 12/02/2015 03:22 PM, Paolo Bonzini wrote:
>>
>> On 30/11/2015 17:22, Andrey Smetanin wrote:
>>> enum hv_message_type inside struct hv_message, hv_post_message
>>> is not size portable. Replace enum by u32.
>> It's only non-portable inside structs.  Okay to apply just these:
>>
>> @@ -172,7 +174,7 @@ union hv_message_flags {
>>
>>   /* Define synthetic interrupt controller message header. */
>>   struct hv_message_header {
>> -    u32 message_type;
>> +    enum hv_message_type message_type;
>>       u8 payload_size;
>>       union hv_message_flags message_flags;
>>       u8 reserved[2];
>> @@ -345,7 +347,7 @@ enum hv_call_code {
>>   struct hv_input_post_message {
>>       union hv_connection_id connectionid;
>>       u32 reserved;
>> -    u32 message_type;
>> +    enum hv_message_type message_type;
>>       u32 payload_size;
>>       u64 payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
>>   };
>>
>> ?
>>
>> Paolo
> sorry for the delay.
> 
> Andrey is on vacation till the end of the week.
> 
> This could be not enough for some compilers as this exact
> enum could be signed and unsigned depends upon the
> implementation of the compiler and if it is signed we
> can face signed/unsigned comparison in ifs.

But why is that a problem?  The issue is pre-existing anyway; the only
one that can cause bugs when moving code to uapi/ (i.e. which means it
can be used on non-x86 platforms) is the size of the enum, not the
signedness.

Paolo

> Vitaly, by the way, this code is a bit rotten. The only caller of
> hv_post_message calls it with message type exactly written
> as "1", which is not defined in the enum.
> 
> /*
>  * vmbus_post_msg - Send a msg on the vmbus's message connection
>  */
> int vmbus_post_msg(void *buffer, size_t buflen)
> {
>     ...
>     ret = hv_post_message(conn_id, 1, buffer, buflen);
> 
> Den

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

* Re: [Qemu-devel] [PATCH v2 1/9] drivers/hv: replace enum hv_message_type by u32
@ 2015-12-04 14:41         ` Paolo Bonzini
  0 siblings, 0 replies; 34+ messages in thread
From: Paolo Bonzini @ 2015-12-04 14:41 UTC (permalink / raw)
  To: Denis V. Lunev, Andrey Smetanin, kvm, Vitaly Kuznetsov
  Cc: Gleb Natapov, Haiyang Zhang, K. Y. Srinivasan, Roman Kagan, qemu-devel



On 04/12/2015 15:33, Denis V. Lunev wrote:
> On 12/02/2015 03:22 PM, Paolo Bonzini wrote:
>>
>> On 30/11/2015 17:22, Andrey Smetanin wrote:
>>> enum hv_message_type inside struct hv_message, hv_post_message
>>> is not size portable. Replace enum by u32.
>> It's only non-portable inside structs.  Okay to apply just these:
>>
>> @@ -172,7 +174,7 @@ union hv_message_flags {
>>
>>   /* Define synthetic interrupt controller message header. */
>>   struct hv_message_header {
>> -    u32 message_type;
>> +    enum hv_message_type message_type;
>>       u8 payload_size;
>>       union hv_message_flags message_flags;
>>       u8 reserved[2];
>> @@ -345,7 +347,7 @@ enum hv_call_code {
>>   struct hv_input_post_message {
>>       union hv_connection_id connectionid;
>>       u32 reserved;
>> -    u32 message_type;
>> +    enum hv_message_type message_type;
>>       u32 payload_size;
>>       u64 payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
>>   };
>>
>> ?
>>
>> Paolo
> sorry for the delay.
> 
> Andrey is on vacation till the end of the week.
> 
> This could be not enough for some compilers as this exact
> enum could be signed and unsigned depends upon the
> implementation of the compiler and if it is signed we
> can face signed/unsigned comparison in ifs.

But why is that a problem?  The issue is pre-existing anyway; the only
one that can cause bugs when moving code to uapi/ (i.e. which means it
can be used on non-x86 platforms) is the size of the enum, not the
signedness.

Paolo

> Vitaly, by the way, this code is a bit rotten. The only caller of
> hv_post_message calls it with message type exactly written
> as "1", which is not defined in the enum.
> 
> /*
>  * vmbus_post_msg - Send a msg on the vmbus's message connection
>  */
> int vmbus_post_msg(void *buffer, size_t buflen)
> {
>     ...
>     ret = hv_post_message(conn_id, 1, buffer, buflen);
> 
> Den

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

* Re: [PATCH v2 1/9] drivers/hv: replace enum hv_message_type by u32
  2015-12-04 14:41         ` [Qemu-devel] " Paolo Bonzini
@ 2015-12-04 16:55           ` Denis V. Lunev
  -1 siblings, 0 replies; 34+ messages in thread
From: Denis V. Lunev @ 2015-12-04 16:55 UTC (permalink / raw)
  To: Paolo Bonzini, Andrey Smetanin, kvm, Vitaly Kuznetsov
  Cc: Gleb Natapov, Haiyang Zhang, K. Y. Srinivasan, Roman Kagan, qemu-devel

On 12/04/2015 05:41 PM, Paolo Bonzini wrote:
>
> On 04/12/2015 15:33, Denis V. Lunev wrote:
>> On 12/02/2015 03:22 PM, Paolo Bonzini wrote:
>>> On 30/11/2015 17:22, Andrey Smetanin wrote:
>>>> enum hv_message_type inside struct hv_message, hv_post_message
>>>> is not size portable. Replace enum by u32.
>>> It's only non-portable inside structs.  Okay to apply just these:
>>>
>>> @@ -172,7 +174,7 @@ union hv_message_flags {
>>>
>>>    /* Define synthetic interrupt controller message header. */
>>>    struct hv_message_header {
>>> -    u32 message_type;
>>> +    enum hv_message_type message_type;
>>>        u8 payload_size;
>>>        union hv_message_flags message_flags;
>>>        u8 reserved[2];
>>> @@ -345,7 +347,7 @@ enum hv_call_code {
>>>    struct hv_input_post_message {
>>>        union hv_connection_id connectionid;
>>>        u32 reserved;
>>> -    u32 message_type;
>>> +    enum hv_message_type message_type;
>>>        u32 payload_size;
>>>        u64 payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
>>>    };
>>>
>>> ?
>>>
>>> Paolo
>> sorry for the delay.
>>
>> Andrey is on vacation till the end of the week.
>>
>> This could be not enough for some compilers as this exact
>> enum could be signed and unsigned depends upon the
>> implementation of the compiler and if it is signed we
>> can face signed/unsigned comparison in ifs.
> But why is that a problem?  The issue is pre-existing anyway; the only
> one that can cause bugs when moving code to uapi/ (i.e. which means it
> can be used on non-x86 platforms) is the size of the enum, not the
> signedness.
>
> Paolo
we are now comparing enum with enum which are the same type.
With the change you are proposing we will compare enum
with u32 which are different.

Original suggestion from Andrey was safe in this respect.

Den

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

* Re: [Qemu-devel] [PATCH v2 1/9] drivers/hv: replace enum hv_message_type by u32
@ 2015-12-04 16:55           ` Denis V. Lunev
  0 siblings, 0 replies; 34+ messages in thread
From: Denis V. Lunev @ 2015-12-04 16:55 UTC (permalink / raw)
  To: Paolo Bonzini, Andrey Smetanin, kvm, Vitaly Kuznetsov
  Cc: Gleb Natapov, Haiyang Zhang, K. Y. Srinivasan, Roman Kagan, qemu-devel

On 12/04/2015 05:41 PM, Paolo Bonzini wrote:
>
> On 04/12/2015 15:33, Denis V. Lunev wrote:
>> On 12/02/2015 03:22 PM, Paolo Bonzini wrote:
>>> On 30/11/2015 17:22, Andrey Smetanin wrote:
>>>> enum hv_message_type inside struct hv_message, hv_post_message
>>>> is not size portable. Replace enum by u32.
>>> It's only non-portable inside structs.  Okay to apply just these:
>>>
>>> @@ -172,7 +174,7 @@ union hv_message_flags {
>>>
>>>    /* Define synthetic interrupt controller message header. */
>>>    struct hv_message_header {
>>> -    u32 message_type;
>>> +    enum hv_message_type message_type;
>>>        u8 payload_size;
>>>        union hv_message_flags message_flags;
>>>        u8 reserved[2];
>>> @@ -345,7 +347,7 @@ enum hv_call_code {
>>>    struct hv_input_post_message {
>>>        union hv_connection_id connectionid;
>>>        u32 reserved;
>>> -    u32 message_type;
>>> +    enum hv_message_type message_type;
>>>        u32 payload_size;
>>>        u64 payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
>>>    };
>>>
>>> ?
>>>
>>> Paolo
>> sorry for the delay.
>>
>> Andrey is on vacation till the end of the week.
>>
>> This could be not enough for some compilers as this exact
>> enum could be signed and unsigned depends upon the
>> implementation of the compiler and if it is signed we
>> can face signed/unsigned comparison in ifs.
> But why is that a problem?  The issue is pre-existing anyway; the only
> one that can cause bugs when moving code to uapi/ (i.e. which means it
> can be used on non-x86 platforms) is the size of the enum, not the
> signedness.
>
> Paolo
we are now comparing enum with enum which are the same type.
With the change you are proposing we will compare enum
with u32 which are different.

Original suggestion from Andrey was safe in this respect.

Den

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

* Re: [PATCH v2 1/9] drivers/hv: replace enum hv_message_type by u32
  2015-12-04 16:55           ` [Qemu-devel] " Denis V. Lunev
@ 2015-12-04 17:38             ` Paolo Bonzini
  -1 siblings, 0 replies; 34+ messages in thread
From: Paolo Bonzini @ 2015-12-04 17:38 UTC (permalink / raw)
  To: Denis V. Lunev, Andrey Smetanin, kvm, Vitaly Kuznetsov
  Cc: Gleb Natapov, Haiyang Zhang, K. Y. Srinivasan, Roman Kagan, qemu-devel



On 04/12/2015 17:55, Denis V. Lunev wrote:
> On 12/04/2015 05:41 PM, Paolo Bonzini wrote:
>>
>> On 04/12/2015 15:33, Denis V. Lunev wrote:
>>> On 12/02/2015 03:22 PM, Paolo Bonzini wrote:
>>>> On 30/11/2015 17:22, Andrey Smetanin wrote:
>>>>> enum hv_message_type inside struct hv_message, hv_post_message
>>>>> is not size portable. Replace enum by u32.
>>>> It's only non-portable inside structs.  Okay to apply just these:
>>>>
>>>> @@ -172,7 +174,7 @@ union hv_message_flags {
>>>>
>>>>    /* Define synthetic interrupt controller message header. */
>>>>    struct hv_message_header {
>>>> -    u32 message_type;
>>>> +    enum hv_message_type message_type;
>>>>        u8 payload_size;
>>>>        union hv_message_flags message_flags;
>>>>        u8 reserved[2];
>>>> @@ -345,7 +347,7 @@ enum hv_call_code {
>>>>    struct hv_input_post_message {
>>>>        union hv_connection_id connectionid;
>>>>        u32 reserved;
>>>> -    u32 message_type;
>>>> +    enum hv_message_type message_type;
>>>>        u32 payload_size;
>>>>        u64 payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
>>>>    };
>>>>
>>>> ?
>>>>
>>>> Paolo
>>> sorry for the delay.
>>>
>>> Andrey is on vacation till the end of the week.
>>>
>>> This could be not enough for some compilers as this exact
>>> enum could be signed and unsigned depends upon the
>>> implementation of the compiler and if it is signed we
>>> can face signed/unsigned comparison in ifs.
>> But why is that a problem?  The issue is pre-existing anyway; the only
>> one that can cause bugs when moving code to uapi/ (i.e. which means it
>> can be used on non-x86 platforms) is the size of the enum, not the
>> signedness.
>
> we are now comparing enum with enum which are the same type.
> With the change you are proposing we will compare enum
> with u32 which are different.

This is only an issue in C++.

> Original suggestion from Andrey was safe in this respect.

Sure, but it makes code less clear.

Paolo

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

* Re: [Qemu-devel] [PATCH v2 1/9] drivers/hv: replace enum hv_message_type by u32
@ 2015-12-04 17:38             ` Paolo Bonzini
  0 siblings, 0 replies; 34+ messages in thread
From: Paolo Bonzini @ 2015-12-04 17:38 UTC (permalink / raw)
  To: Denis V. Lunev, Andrey Smetanin, kvm, Vitaly Kuznetsov
  Cc: Gleb Natapov, Haiyang Zhang, K. Y. Srinivasan, Roman Kagan, qemu-devel



On 04/12/2015 17:55, Denis V. Lunev wrote:
> On 12/04/2015 05:41 PM, Paolo Bonzini wrote:
>>
>> On 04/12/2015 15:33, Denis V. Lunev wrote:
>>> On 12/02/2015 03:22 PM, Paolo Bonzini wrote:
>>>> On 30/11/2015 17:22, Andrey Smetanin wrote:
>>>>> enum hv_message_type inside struct hv_message, hv_post_message
>>>>> is not size portable. Replace enum by u32.
>>>> It's only non-portable inside structs.  Okay to apply just these:
>>>>
>>>> @@ -172,7 +174,7 @@ union hv_message_flags {
>>>>
>>>>    /* Define synthetic interrupt controller message header. */
>>>>    struct hv_message_header {
>>>> -    u32 message_type;
>>>> +    enum hv_message_type message_type;
>>>>        u8 payload_size;
>>>>        union hv_message_flags message_flags;
>>>>        u8 reserved[2];
>>>> @@ -345,7 +347,7 @@ enum hv_call_code {
>>>>    struct hv_input_post_message {
>>>>        union hv_connection_id connectionid;
>>>>        u32 reserved;
>>>> -    u32 message_type;
>>>> +    enum hv_message_type message_type;
>>>>        u32 payload_size;
>>>>        u64 payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
>>>>    };
>>>>
>>>> ?
>>>>
>>>> Paolo
>>> sorry for the delay.
>>>
>>> Andrey is on vacation till the end of the week.
>>>
>>> This could be not enough for some compilers as this exact
>>> enum could be signed and unsigned depends upon the
>>> implementation of the compiler and if it is signed we
>>> can face signed/unsigned comparison in ifs.
>> But why is that a problem?  The issue is pre-existing anyway; the only
>> one that can cause bugs when moving code to uapi/ (i.e. which means it
>> can be used on non-x86 platforms) is the size of the enum, not the
>> signedness.
>
> we are now comparing enum with enum which are the same type.
> With the change you are proposing we will compare enum
> with u32 which are different.

This is only an issue in C++.

> Original suggestion from Andrey was safe in this respect.

Sure, but it makes code less clear.

Paolo

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

* Re: [PATCH v2 1/9] drivers/hv: replace enum hv_message_type by u32
  2015-12-04 17:38             ` [Qemu-devel] " Paolo Bonzini
@ 2015-12-04 18:00               ` Denis V. Lunev
  -1 siblings, 0 replies; 34+ messages in thread
From: Denis V. Lunev @ 2015-12-04 18:00 UTC (permalink / raw)
  To: Paolo Bonzini, Andrey Smetanin, kvm, Vitaly Kuznetsov
  Cc: Gleb Natapov, K. Y. Srinivasan, Haiyang Zhang, Roman Kagan, qemu-devel

On 12/04/2015 08:38 PM, Paolo Bonzini wrote:
>
> On 04/12/2015 17:55, Denis V. Lunev wrote:
>> On 12/04/2015 05:41 PM, Paolo Bonzini wrote:
>>> On 04/12/2015 15:33, Denis V. Lunev wrote:
>>>> On 12/02/2015 03:22 PM, Paolo Bonzini wrote:
>>>>> On 30/11/2015 17:22, Andrey Smetanin wrote:
>>>>>> enum hv_message_type inside struct hv_message, hv_post_message
>>>>>> is not size portable. Replace enum by u32.
>>>>> It's only non-portable inside structs.  Okay to apply just these:
>>>>>
>>>>> @@ -172,7 +174,7 @@ union hv_message_flags {
>>>>>
>>>>>     /* Define synthetic interrupt controller message header. */
>>>>>     struct hv_message_header {
>>>>> -    u32 message_type;
>>>>> +    enum hv_message_type message_type;
>>>>>         u8 payload_size;
>>>>>         union hv_message_flags message_flags;
>>>>>         u8 reserved[2];
>>>>> @@ -345,7 +347,7 @@ enum hv_call_code {
>>>>>     struct hv_input_post_message {
>>>>>         union hv_connection_id connectionid;
>>>>>         u32 reserved;
>>>>> -    u32 message_type;
>>>>> +    enum hv_message_type message_type;
>>>>>         u32 payload_size;
>>>>>         u64 payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
>>>>>     };
>>>>>
>>>>> ?
>>>>>
>>>>> Paolo
>>>> sorry for the delay.
>>>>
>>>> Andrey is on vacation till the end of the week.
>>>>
>>>> This could be not enough for some compilers as this exact
>>>> enum could be signed and unsigned depends upon the
>>>> implementation of the compiler and if it is signed we
>>>> can face signed/unsigned comparison in ifs.
>>> But why is that a problem?  The issue is pre-existing anyway; the only
>>> one that can cause bugs when moving code to uapi/ (i.e. which means it
>>> can be used on non-x86 platforms) is the size of the enum, not the
>>> signedness.
>> we are now comparing enum with enum which are the same type.
>> With the change you are proposing we will compare enum
>> with u32 which are different.
> This is only an issue in C++.
>
>> Original suggestion from Andrey was safe in this respect.
> Sure, but it makes code less clear.
>
> Paolo

ok, this seems reasonable. Why not to reduce the patch :)
We'll send an update on Monday.

Are there any other issue with the patchset?

Den

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

* Re: [Qemu-devel] [PATCH v2 1/9] drivers/hv: replace enum hv_message_type by u32
@ 2015-12-04 18:00               ` Denis V. Lunev
  0 siblings, 0 replies; 34+ messages in thread
From: Denis V. Lunev @ 2015-12-04 18:00 UTC (permalink / raw)
  To: Paolo Bonzini, Andrey Smetanin, kvm, Vitaly Kuznetsov
  Cc: Gleb Natapov, Haiyang Zhang, K. Y. Srinivasan, Roman Kagan, qemu-devel

On 12/04/2015 08:38 PM, Paolo Bonzini wrote:
>
> On 04/12/2015 17:55, Denis V. Lunev wrote:
>> On 12/04/2015 05:41 PM, Paolo Bonzini wrote:
>>> On 04/12/2015 15:33, Denis V. Lunev wrote:
>>>> On 12/02/2015 03:22 PM, Paolo Bonzini wrote:
>>>>> On 30/11/2015 17:22, Andrey Smetanin wrote:
>>>>>> enum hv_message_type inside struct hv_message, hv_post_message
>>>>>> is not size portable. Replace enum by u32.
>>>>> It's only non-portable inside structs.  Okay to apply just these:
>>>>>
>>>>> @@ -172,7 +174,7 @@ union hv_message_flags {
>>>>>
>>>>>     /* Define synthetic interrupt controller message header. */
>>>>>     struct hv_message_header {
>>>>> -    u32 message_type;
>>>>> +    enum hv_message_type message_type;
>>>>>         u8 payload_size;
>>>>>         union hv_message_flags message_flags;
>>>>>         u8 reserved[2];
>>>>> @@ -345,7 +347,7 @@ enum hv_call_code {
>>>>>     struct hv_input_post_message {
>>>>>         union hv_connection_id connectionid;
>>>>>         u32 reserved;
>>>>> -    u32 message_type;
>>>>> +    enum hv_message_type message_type;
>>>>>         u32 payload_size;
>>>>>         u64 payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
>>>>>     };
>>>>>
>>>>> ?
>>>>>
>>>>> Paolo
>>>> sorry for the delay.
>>>>
>>>> Andrey is on vacation till the end of the week.
>>>>
>>>> This could be not enough for some compilers as this exact
>>>> enum could be signed and unsigned depends upon the
>>>> implementation of the compiler and if it is signed we
>>>> can face signed/unsigned comparison in ifs.
>>> But why is that a problem?  The issue is pre-existing anyway; the only
>>> one that can cause bugs when moving code to uapi/ (i.e. which means it
>>> can be used on non-x86 platforms) is the size of the enum, not the
>>> signedness.
>> we are now comparing enum with enum which are the same type.
>> With the change you are proposing we will compare enum
>> with u32 which are different.
> This is only an issue in C++.
>
>> Original suggestion from Andrey was safe in this respect.
> Sure, but it makes code less clear.
>
> Paolo

ok, this seems reasonable. Why not to reduce the patch :)
We'll send an update on Monday.

Are there any other issue with the patchset?

Den

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

* Re: [PATCH v2 1/9] drivers/hv: replace enum hv_message_type by u32
  2015-12-04 18:00               ` [Qemu-devel] " Denis V. Lunev
@ 2015-12-04 18:12                 ` Paolo Bonzini
  -1 siblings, 0 replies; 34+ messages in thread
From: Paolo Bonzini @ 2015-12-04 18:12 UTC (permalink / raw)
  To: Denis V. Lunev
  Cc: Andrey Smetanin, kvm, Vitaly Kuznetsov, Gleb Natapov,
	K. Y. Srinivasan, Haiyang Zhang, Roman Kagan, qemu-devel


> >> we are now comparing enum with enum which are the same type.
> >> With the change you are proposing we will compare enum
> >> with u32 which are different.
> > This is only an issue in C++.
> >
> >> Original suggestion from Andrey was safe in this respect.
> > Sure, but it makes code less clear.
> >
> > Paolo
> 
> ok, this seems reasonable. Why not to reduce the patch :)
> We'll send an update on Monday.
> 
> Are there any other issue with the patchset?

No, I can also do the change myself. Check kvm/queue.

Paolo

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

* Re: [Qemu-devel] [PATCH v2 1/9] drivers/hv: replace enum hv_message_type by u32
@ 2015-12-04 18:12                 ` Paolo Bonzini
  0 siblings, 0 replies; 34+ messages in thread
From: Paolo Bonzini @ 2015-12-04 18:12 UTC (permalink / raw)
  To: Denis V. Lunev
  Cc: kvm, Gleb Natapov, Haiyang Zhang, qemu-devel, Roman Kagan,
	Andrey Smetanin, Vitaly Kuznetsov, K. Y. Srinivasan


> >> we are now comparing enum with enum which are the same type.
> >> With the change you are proposing we will compare enum
> >> with u32 which are different.
> > This is only an issue in C++.
> >
> >> Original suggestion from Andrey was safe in this respect.
> > Sure, but it makes code less clear.
> >
> > Paolo
> 
> ok, this seems reasonable. Why not to reduce the patch :)
> We'll send an update on Monday.
> 
> Are there any other issue with the patchset?

No, I can also do the change myself. Check kvm/queue.

Paolo

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

end of thread, other threads:[~2015-12-04 18:12 UTC | newest]

Thread overview: 34+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-11-30 16:22 [PATCH v2 0/9] KVM: Hyper-V SynIC timers Andrey Smetanin
2015-11-30 16:22 ` [Qemu-devel] " Andrey Smetanin
2015-11-30 16:22 ` [PATCH v2 1/9] drivers/hv: replace enum hv_message_type by u32 Andrey Smetanin
2015-11-30 16:22   ` [Qemu-devel] " Andrey Smetanin
2015-12-02 12:22   ` Paolo Bonzini
2015-12-02 12:22     ` [Qemu-devel] " Paolo Bonzini
2015-12-04 14:33     ` Denis V. Lunev
2015-12-04 14:33       ` [Qemu-devel] " Denis V. Lunev
2015-12-04 14:41       ` Paolo Bonzini
2015-12-04 14:41         ` [Qemu-devel] " Paolo Bonzini
2015-12-04 16:55         ` Denis V. Lunev
2015-12-04 16:55           ` [Qemu-devel] " Denis V. Lunev
2015-12-04 17:38           ` Paolo Bonzini
2015-12-04 17:38             ` [Qemu-devel] " Paolo Bonzini
2015-12-04 18:00             ` Denis V. Lunev
2015-12-04 18:00               ` [Qemu-devel] " Denis V. Lunev
2015-12-04 18:12               ` Paolo Bonzini
2015-12-04 18:12                 ` [Qemu-devel] " Paolo Bonzini
2015-11-30 16:22 ` [PATCH v2 2/9] drivers/hv: Move HV_SYNIC_STIMER_COUNT into Hyper-V UAPI x86 header Andrey Smetanin
2015-11-30 16:22   ` [Qemu-devel] " Andrey Smetanin
2015-11-30 16:22 ` [PATCH v2 3/9] drivers/hv: Move struct hv_message into UAPI Hyper-V " Andrey Smetanin
2015-11-30 16:22   ` [Qemu-devel] " Andrey Smetanin
2015-11-30 16:22 ` [PATCH v2 4/9] drivers/hv: Move struct hv_timer_message_payload " Andrey Smetanin
2015-11-30 16:22   ` [Qemu-devel] " Andrey Smetanin
2015-11-30 16:22 ` [PATCH v2 5/9] kvm/x86: Rearrange func's declarations inside Hyper-V header Andrey Smetanin
2015-11-30 16:22   ` [Qemu-devel] " Andrey Smetanin
2015-11-30 16:22 ` [PATCH v2 6/9] kvm/x86: Added Hyper-V vcpu_to_hv_vcpu()/hv_vcpu_to_vcpu() helpers Andrey Smetanin
2015-11-30 16:22   ` [Qemu-devel] " Andrey Smetanin
2015-11-30 16:22 ` [PATCH v2 7/9] kvm/x86: Hyper-V internal helper to read MSR HV_X64_MSR_TIME_REF_COUNT Andrey Smetanin
2015-11-30 16:22   ` [Qemu-devel] " Andrey Smetanin
2015-11-30 16:22 ` [PATCH v2 8/9] kvm/x86: Hyper-V SynIC message slot pending clearing at SINT ack Andrey Smetanin
2015-11-30 16:22   ` [Qemu-devel] " Andrey Smetanin
2015-11-30 16:22 ` [PATCH v2 9/9] kvm/x86: Hyper-V SynIC timers Andrey Smetanin
2015-11-30 16:22   ` [Qemu-devel] " Andrey Smetanin

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.