Re: [Qemu-devel] [PATCH v3 8/9] kvm/x86: Hyper-V synthetic interrupt controller

2015-10-29 Thread Andrey Smetanin


On 10/28/2015 08:41 PM, Paolo Bonzini wrote:

Hi Andrey,

just one question.  Is kvm_arch_set_irq actually needed?  I think
everything should work fine without it.  Can you check?  If so, I can
remove it myself and revert the patch that introduced the hook.


Hi Paolo,

I have checked that Hyper-V SynIC unit test and some hand-made tests 
with Windows guest(with enabled SynIC) works fine without 
kvm_arch_set_irq. It will be nice

to remove this function.

Thanks

Paolo

On 22/10/2015 18:09, Andrey Smetanin wrote:

SynIC (synthetic interrupt controller) is a lapic extension,
which is controlled via MSRs and maintains for each vCPU
  - 16 synthetic interrupt "lines" (SINT's); each can be configured to
trigger a specific interrupt vector optionally with auto-EOI
semantics
  - a message page in the guest memory with 16 256-byte per-SINT message
slots
  - an event flag page in the guest memory with 16 2048-bit per-SINT
event flag areas

The host triggers a SINT whenever it delivers a new message to the
corresponding slot or flips an event flag bit in the corresponding area.
The guest informs the host that it can try delivering a message by
explicitly asserting EOI in lapic or writing to End-Of-Message (EOM)
MSR.

The userspace (qemu) triggers interrupts and receives EOM notifications
via irqfd with resampler; for that, a GSI is allocated for each
configured SINT, and irq_routing api is extended to support GSI-SINT
mapping.

Signed-off-by: Andrey Smetanin 
Reviewed-by: Roman Kagan 
Signed-off-by: Denis V. Lunev 
CC: Vitaly Kuznetsov 
CC: "K. Y. Srinivasan" 
CC: Gleb Natapov 
CC: Paolo Bonzini 
CC: Roman Kagan 

Changes v3:
* added KVM_CAP_HYPERV_SYNIC and KVM_IRQ_ROUTING_HV_SINT notes into
docs

Changes v2:
* do not use posted interrupts for Hyper-V SynIC AutoEOI vectors
* add Hyper-V SynIC vectors into EOI exit bitmap
* Hyper-V SyniIC SINT msr write logic simplified
---
  Documentation/virtual/kvm/api.txt |  14 ++
  arch/x86/include/asm/kvm_host.h   |  14 ++
  arch/x86/kvm/hyperv.c | 297 ++
  arch/x86/kvm/hyperv.h |  21 +++
  arch/x86/kvm/irq_comm.c   |  34 +
  arch/x86/kvm/lapic.c  |  18 ++-
  arch/x86/kvm/lapic.h  |   5 +
  arch/x86/kvm/x86.c|  12 +-
  include/linux/kvm_host.h  |   6 +
  include/uapi/linux/kvm.h  |   8 +
  10 files changed, 421 insertions(+), 8 deletions(-)

diff --git a/Documentation/virtual/kvm/api.txt 
b/Documentation/virtual/kvm/api.txt
index 092ee9f..8710418 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -1451,6 +1451,7 @@ struct kvm_irq_routing_entry {
struct kvm_irq_routing_irqchip irqchip;
struct kvm_irq_routing_msi msi;
struct kvm_irq_routing_s390_adapter adapter;
+   struct kvm_irq_routing_hv_sint hv_sint;
__u32 pad[8];
} u;
  };
@@ -1459,6 +1460,7 @@ struct kvm_irq_routing_entry {
  #define KVM_IRQ_ROUTING_IRQCHIP 1
  #define KVM_IRQ_ROUTING_MSI 2
  #define KVM_IRQ_ROUTING_S390_ADAPTER 3
+#define KVM_IRQ_ROUTING_HV_SINT 4

  No flags are specified so far, the corresponding field must be set to zero.

@@ -1482,6 +1484,10 @@ struct kvm_irq_routing_s390_adapter {
__u32 adapter_id;
  };

+struct kvm_irq_routing_hv_sint {
+   __u32 vcpu;
+   __u32 sint;
+};

  4.53 KVM_ASSIGN_SET_MSIX_NR (deprecated)

@@ -3685,3 +3691,11 @@ available, means that that the kernel has an 
implementation of the
  H_RANDOM hypercall backed by a hardware random-number generator.
  If present, the kernel H_RANDOM handler can be enabled for guest use
  with the KVM_CAP_PPC_ENABLE_HCALL capability.
+
+8.2 KVM_CAP_HYPERV_SYNIC
+
+Architectures: x86
+This capability, if KVM_CHECK_EXTENSION indicates that it is
+available, means that that the kernel has an implementation of the
+Hyper-V Synthetic interrupt controller(SynIC). SynIC is used to
+support Windows Hyper-V based guest paravirt drivers(VMBus).
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 3c6327d..8434f88 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -25,6 +25,7 @@
  #include 
  #include 
  #include 
+#include 

  #include 
  #include 
@@ -374,10 +375,23 @@ struct kvm_mtrr {
struct list_head head;
  };

+/* Hyper-V synthetic interrupt controller (SynIC)*/
+struct kvm_vcpu_hv_synic {
+   u64 version;
+   u64 control;
+   u64 msg_page;
+   u64 evt_page;
+   atomic64_t sint[HV_SYNIC_SINT_COUNT];
+   atomic_t sint_to_gsi[HV_SYNIC_SINT_COUNT];
+   DECLARE_BITMAP(auto_eoi_bitmap, 256);
+   DECLARE_BITMAP(vec_bitmap, 256);
+};
+
  /* Hyper-V per vcpu emulation context */
  struct kvm_vcpu_hv {
u64 hv_vapic;
s64 runtime_offset;
+   struct kvm_vcpu_hv_synic synic;
  };

  struct kvm_vcpu_arch {
diff --git a/arch/x86/kv

Re: [Qemu-devel] [PATCH v3 9/9] kvm/x86: Hyper-V kvm exit

2015-11-03 Thread Andrey Smetanin



On 11/03/2015 04:28 PM, Paolo Bonzini wrote:



On 22/10/2015 18:10, Andrey Smetanin wrote:

A new vcpu exit is introduced to notify the userspace of the
changes in Hyper-V SynIC configuration triggered by guest writing to the
corresponding MSRs.

Changes v3:
* added KVM_EXIT_HYPERV types and structs notes into docs

Signed-off-by: Andrey Smetanin 
Reviewed-by: Roman Kagan 
Signed-off-by: Denis V. Lunev 
CC: Vitaly Kuznetsov 
CC: "K. Y. Srinivasan" 
CC: Gleb Natapov 
CC: Paolo Bonzini 
CC: Roman Kagan 

---
  Documentation/virtual/kvm/api.txt | 22 ++
  arch/x86/include/asm/kvm_host.h   |  1 +
  arch/x86/kvm/hyperv.c | 17 +
  arch/x86/kvm/x86.c|  6 ++
  include/linux/kvm_host.h  |  1 +
  include/uapi/linux/kvm.h  | 17 +
  6 files changed, 64 insertions(+)

diff --git a/Documentation/virtual/kvm/api.txt 
b/Documentation/virtual/kvm/api.txt
index 8710418..a6858eb 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -3337,6 +3337,28 @@ the userspace IOAPIC should process the EOI and 
retrigger the interrupt if
  it is still asserted.  Vector is the LAPIC interrupt vector for which the
  EOI was received.

+   struct kvm_hyperv_exit {
+#define KVM_EXIT_HYPERV_SYNIC  1
+   __u32 type;
+   union {
+   struct {
+   __u32 msr;
+   __u64 control;
+   __u64 evt_page;
+   __u64 msg_page;
+   } synic;
+   } u;
+   };
+   /* KVM_EXIT_HYPERV */
+struct kvm_hyperv_exit hyperv;
+Indicates that the VCPU exits into userspace to process some tasks
+related to Hyper-V emulation.
+Valid values for 'type' are:
+   KVM_EXIT_HYPERV_SYNIC -- synchronously notify user-space about
+Hyper-V SynIC state change. Notification is used to remap SynIC
+event/message pages and to enable/disable SynIC messages/events processing
+in userspace.
+
/* Fix the size of the union. */
char padding[256];
};
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 8434f88..54c90d3 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -392,6 +392,7 @@ struct kvm_vcpu_hv {
u64 hv_vapic;
s64 runtime_offset;
struct kvm_vcpu_hv_synic synic;
+   struct kvm_hyperv_exit exit;
  };

  struct kvm_vcpu_arch {
diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index 8ff71f3..9443920 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -129,6 +129,20 @@ static void kvm_hv_notify_acked_sint(struct kvm_vcpu 
*vcpu, u32 sint)
srcu_read_unlock(&kvm->irq_srcu, idx);
  }

+static void synic_exit(struct kvm_vcpu_hv_synic *synic, u32 msr)
+{
+   struct kvm_vcpu *vcpu = synic_to_vcpu(synic);
+   struct kvm_vcpu_hv *hv_vcpu = &vcpu->arch.hyperv;
+
+   hv_vcpu->exit.type = KVM_EXIT_HYPERV_SYNIC;
+   hv_vcpu->exit.u.synic.msr = msr;
+   hv_vcpu->exit.u.synic.control = synic->control;
+   hv_vcpu->exit.u.synic.evt_page = synic->evt_page;
+   hv_vcpu->exit.u.synic.msg_page = synic->msg_page;
+
+   kvm_make_request(KVM_REQ_HV_EXIT, vcpu);
+}
+
  static int synic_set_msr(struct kvm_vcpu_hv_synic *synic,
 u32 msr, u64 data, bool host)
  {
@@ -141,6 +155,7 @@ static int synic_set_msr(struct kvm_vcpu_hv_synic *synic,
switch (msr) {
case HV_X64_MSR_SCONTROL:
synic->control = data;
+   synic_exit(synic, msr);


Another note.  I am getting:

EAX= EBX= ECX= EDX=0663
ESI= EDI= EBP= ESP=
EIP=fff0 EFL=0002 [---] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =   9300
CS =f000   9b00
SS =   9300
DS =   9300
FS =   9300
GS =   9300
LDT=   8200
TR =   8b00
GDT=  
IDT=  
CR0=6010 CR2= CR3= CR4=
DR0= DR1= DR2=
DR3=
DR6=0ff0 DR7=0400
EFER=
Code=90 90 90 90 eb c3 90 90 90 90 90 90 00 00 00 00 56 54 46 00 <90> 90
eb ac 90 90 90 90 90 90 90 90 90 90 90 90 00 00 00 00 00 00 00 00 00 00
00 00 00 00

if I run a patched QEMU but I *do not* enable the synthetic interrupt
controller.  I can fix it by wrapping the calls to synic_exit with "if
(!host)", but I haven't checked yet the source---so that may not 

Re: [Qemu-devel] [PATCH v3 9/9] kvm/x86: Hyper-V kvm exit

2015-11-03 Thread Andrey Smetanin



On 11/03/2015 04:28 PM, Paolo Bonzini wrote:



On 22/10/2015 18:10, Andrey Smetanin wrote:

A new vcpu exit is introduced to notify the userspace of the
changes in Hyper-V SynIC configuration triggered by guest writing to the
corresponding MSRs.

Changes v3:
* added KVM_EXIT_HYPERV types and structs notes into docs

Signed-off-by: Andrey Smetanin 
Reviewed-by: Roman Kagan 
Signed-off-by: Denis V. Lunev 
CC: Vitaly Kuznetsov 
CC: "K. Y. Srinivasan" 
CC: Gleb Natapov 
CC: Paolo Bonzini 
CC: Roman Kagan 

---
  Documentation/virtual/kvm/api.txt | 22 ++
  arch/x86/include/asm/kvm_host.h   |  1 +
  arch/x86/kvm/hyperv.c | 17 +
  arch/x86/kvm/x86.c|  6 ++
  include/linux/kvm_host.h  |  1 +
  include/uapi/linux/kvm.h  | 17 +
  6 files changed, 64 insertions(+)

diff --git a/Documentation/virtual/kvm/api.txt 
b/Documentation/virtual/kvm/api.txt
index 8710418..a6858eb 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -3337,6 +3337,28 @@ the userspace IOAPIC should process the EOI and 
retrigger the interrupt if
  it is still asserted.  Vector is the LAPIC interrupt vector for which the
  EOI was received.

+   struct kvm_hyperv_exit {
+#define KVM_EXIT_HYPERV_SYNIC  1
+   __u32 type;
+   union {
+   struct {
+   __u32 msr;
+   __u64 control;
+   __u64 evt_page;
+   __u64 msg_page;
+   } synic;
+   } u;
+   };
+   /* KVM_EXIT_HYPERV */
+struct kvm_hyperv_exit hyperv;
+Indicates that the VCPU exits into userspace to process some tasks
+related to Hyper-V emulation.
+Valid values for 'type' are:
+   KVM_EXIT_HYPERV_SYNIC -- synchronously notify user-space about
+Hyper-V SynIC state change. Notification is used to remap SynIC
+event/message pages and to enable/disable SynIC messages/events processing
+in userspace.
+
/* Fix the size of the union. */
char padding[256];
};
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 8434f88..54c90d3 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -392,6 +392,7 @@ struct kvm_vcpu_hv {
u64 hv_vapic;
s64 runtime_offset;
struct kvm_vcpu_hv_synic synic;
+   struct kvm_hyperv_exit exit;
  };

  struct kvm_vcpu_arch {
diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index 8ff71f3..9443920 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -129,6 +129,20 @@ static void kvm_hv_notify_acked_sint(struct kvm_vcpu 
*vcpu, u32 sint)
srcu_read_unlock(&kvm->irq_srcu, idx);
  }

+static void synic_exit(struct kvm_vcpu_hv_synic *synic, u32 msr)
+{
+   struct kvm_vcpu *vcpu = synic_to_vcpu(synic);
+   struct kvm_vcpu_hv *hv_vcpu = &vcpu->arch.hyperv;
+
+   hv_vcpu->exit.type = KVM_EXIT_HYPERV_SYNIC;
+   hv_vcpu->exit.u.synic.msr = msr;
+   hv_vcpu->exit.u.synic.control = synic->control;
+   hv_vcpu->exit.u.synic.evt_page = synic->evt_page;
+   hv_vcpu->exit.u.synic.msg_page = synic->msg_page;
+
+   kvm_make_request(KVM_REQ_HV_EXIT, vcpu);
+}
+
  static int synic_set_msr(struct kvm_vcpu_hv_synic *synic,
 u32 msr, u64 data, bool host)
  {
@@ -141,6 +155,7 @@ static int synic_set_msr(struct kvm_vcpu_hv_synic *synic,
switch (msr) {
case HV_X64_MSR_SCONTROL:
synic->control = data;
+   synic_exit(synic, msr);


Another note.  I am getting:

EAX= EBX= ECX= EDX=0663
ESI= EDI= EBP= ESP=
EIP=fff0 EFL=0002 [---] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =   9300
CS =f000   9b00
SS =   9300
DS =   9300
FS =   9300
GS =   9300
LDT=   8200
TR =   8b00
GDT=  
IDT=  
CR0=6010 CR2= CR3= CR4=
DR0= DR1= DR2=
DR3=
DR6=0ff0 DR7=0400
EFER=
Code=90 90 90 90 eb c3 90 90 90 90 90 90 00 00 00 00 56 54 46 00 <90> 90
eb ac 90 90 90 90 90 90 90 90 90 90 90 90 00 00 00 00 00 00 00 00 00 00
00 00 00 00

if I run a patched QEMU but I *do not* enable the synthetic interrupt
controller.  I can fix it by wrapping the calls to synic_exit with "if
(!host)", but I haven't checked yet the source---so that may not

Re: [Qemu-devel] [PATCH v3 9/9] kvm/x86: Hyper-V kvm exit

2015-11-03 Thread Andrey Smetanin



On 11/03/2015 05:51 PM, Paolo Bonzini wrote:



On 03/11/2015 15:36, Andrey Smetanin wrote:



if I run a patched QEMU but I *do not* enable the synthetic interrupt
controller.  I can fix it by wrapping the calls to synic_exit with "if
(!host)", but I haven't checked yet the source---so that may not be the
proper fix.  Sorry for not having looked more in detail.


Could you please specify test case(kvm unit tests ?) and kernel/qemu(if
it's not standard)?


It happens just by starting QEMU.

Kernel: kvm/queue
+ kvm/irqchip: kvm_arch_irq_routing_update renaming split
+ kvm/x86: split ioapic-handled and EOI exit bitmaps
+ kvm/x86: Hyper-V synthetic interrupt controller
+ kvm/x86: Hyper-V kvm exit

QEMU: 3a958f559ecd
+ standard-headers/x86: add Hyper-V SynIC constants
+ target-i386/kvm: Hyper-V SynIC MSR's support
+ linux-headers/kvm: add Hyper-V SynIC irq routing type and struct
+ kvm: Hyper-V SynIC irq routing support
+ linux-headers/kvm: KVM_EXIT_HYPERV type and struct
+ target-i386/hyperv: Hyper-V SynIC SINT routing and vCPU exit
+ hw/misc: Hyper-V test device 'hyperv-testdev'

Can be reproduced just with
"../qemu/+build/x86_64-softmmu/qemu-system-x86_64 --enable-kvm -cpu
kvm64 -display none".


Thanks!
We probably found root case -
qemu reads/writes Hyper-V SynIC msrs just by check SynIC MSR's support 
in kernel. So KVM synic exits into userspace(at SynIC MSR's writes), 
while userspace Hyper-V SynIC handler doesn't expect this exit(cpu 
'hv-synic' option is not set), so handler returns -1 and qemu exits.

Paolo





[Qemu-devel] [PATCH v4 5/5] kvm/x86: Hyper-V kvm exit

2015-11-10 Thread Andrey Smetanin
A new vcpu exit is introduced to notify the userspace of the
changes in Hyper-V SynIC configuration triggered by guest writing to the
corresponding MSRs.

Changes v4:
* exit into userspace only if guest writes into SynIC MSR's

Changes v3:
* added KVM_EXIT_HYPERV types and structs notes into docs

Signed-off-by: Andrey Smetanin 
Reviewed-by: Roman Kagan 
Signed-off-by: Denis V. Lunev 
CC: Gleb Natapov 
CC: Paolo Bonzini 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: qemu-devel@nongnu.org

---
 Documentation/virtual/kvm/api.txt | 22 ++
 arch/x86/include/asm/kvm_host.h   |  1 +
 arch/x86/kvm/hyperv.c | 20 
 arch/x86/kvm/x86.c|  6 ++
 include/linux/kvm_host.h  |  1 +
 include/uapi/linux/kvm.h  | 17 +
 6 files changed, 67 insertions(+)

diff --git a/Documentation/virtual/kvm/api.txt 
b/Documentation/virtual/kvm/api.txt
index 16096a2..abc4f48 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -3337,6 +3337,28 @@ the userspace IOAPIC should process the EOI and 
retrigger the interrupt if
 it is still asserted.  Vector is the LAPIC interrupt vector for which the
 EOI was received.
 
+   struct kvm_hyperv_exit {
+#define KVM_EXIT_HYPERV_SYNIC  1
+   __u32 type;
+   union {
+   struct {
+   __u32 msr;
+   __u64 control;
+   __u64 evt_page;
+   __u64 msg_page;
+   } synic;
+   } u;
+   };
+   /* KVM_EXIT_HYPERV */
+struct kvm_hyperv_exit hyperv;
+Indicates that the VCPU exits into userspace to process some tasks
+related to Hyper-V emulation.
+Valid values for 'type' are:
+   KVM_EXIT_HYPERV_SYNIC -- synchronously notify user-space about
+Hyper-V SynIC state change. Notification is used to remap SynIC
+event/message pages and to enable/disable SynIC messages/events processing
+in userspace.
+
/* Fix the size of the union. */
char padding[256];
};
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index ad29e89..1cefa1e 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -393,6 +393,7 @@ struct kvm_vcpu_hv {
u64 hv_vapic;
s64 runtime_offset;
struct kvm_vcpu_hv_synic synic;
+   struct kvm_hyperv_exit exit;
 };
 
 struct kvm_vcpu_arch {
diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index 83a3c0c..41869a9 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -130,6 +130,20 @@ static void kvm_hv_notify_acked_sint(struct kvm_vcpu 
*vcpu, u32 sint)
srcu_read_unlock(&kvm->irq_srcu, idx);
 }
 
+static void synic_exit(struct kvm_vcpu_hv_synic *synic, u32 msr)
+{
+   struct kvm_vcpu *vcpu = synic_to_vcpu(synic);
+   struct kvm_vcpu_hv *hv_vcpu = &vcpu->arch.hyperv;
+
+   hv_vcpu->exit.type = KVM_EXIT_HYPERV_SYNIC;
+   hv_vcpu->exit.u.synic.msr = msr;
+   hv_vcpu->exit.u.synic.control = synic->control;
+   hv_vcpu->exit.u.synic.evt_page = synic->evt_page;
+   hv_vcpu->exit.u.synic.msg_page = synic->msg_page;
+
+   kvm_make_request(KVM_REQ_HV_EXIT, vcpu);
+}
+
 static int synic_set_msr(struct kvm_vcpu_hv_synic *synic,
 u32 msr, u64 data, bool host)
 {
@@ -145,6 +159,8 @@ static int synic_set_msr(struct kvm_vcpu_hv_synic *synic,
switch (msr) {
case HV_X64_MSR_SCONTROL:
synic->control = data;
+   if (!host)
+   synic_exit(synic, msr);
break;
case HV_X64_MSR_SVERSION:
if (!host) {
@@ -161,6 +177,8 @@ static int synic_set_msr(struct kvm_vcpu_hv_synic *synic,
break;
}
synic->evt_page = data;
+   if (!host)
+   synic_exit(synic, msr);
break;
case HV_X64_MSR_SIMP:
if (data & HV_SYNIC_SIMP_ENABLE)
@@ -170,6 +188,8 @@ static int synic_set_msr(struct kvm_vcpu_hv_synic *synic,
break;
}
synic->msg_page = data;
+   if (!host)
+   synic_exit(synic, msr);
break;
case HV_X64_MSR_EOM: {
int i;
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 41f3030..04daf32 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -6377,6 +6377,12 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
r = 0;
goto out;
}
+   if (kvm_check_request(KVM_RE

[Qemu-devel] [PATCH v2 3/5] kvm: Hyper-V SynIC irq routing support

2015-11-10 Thread Andrey Smetanin
Signed-off-by: Andrey Smetanin 
Reviewed-by: Roman Kagan 
Signed-off-by: Denis V. Lunev 
CC: Paolo Bonzini 
CC: Richard Henderson 
CC: Eduardo Habkost 
CC: "Andreas Färber" 
CC: Marcelo Tosatti 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: k...@vger.kernel.org

---
 include/sysemu/kvm.h |  1 +
 kvm-all.c| 33 +
 2 files changed, 34 insertions(+)

diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index 4ac6176..92ccb35 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -447,6 +447,7 @@ int kvm_irqchip_update_msi_route(KVMState *s, int virq, 
MSIMessage msg,
 void kvm_irqchip_release_virq(KVMState *s, int virq);
 
 int kvm_irqchip_add_adapter_route(KVMState *s, AdapterInfo *adapter);
+int kvm_irqchip_add_hv_sint_route(KVMState *s, uint32_t vcpu, uint32_t sint);
 
 int kvm_irqchip_add_irqfd_notifier_gsi(KVMState *s, EventNotifier *n,
EventNotifier *rn, int virq);
diff --git a/kvm-all.c b/kvm-all.c
index 1bc1273..d36b494 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1297,6 +1297,34 @@ int kvm_irqchip_add_adapter_route(KVMState *s, 
AdapterInfo *adapter)
 return virq;
 }
 
+int kvm_irqchip_add_hv_sint_route(KVMState *s, uint32_t vcpu, uint32_t sint)
+{
+struct kvm_irq_routing_entry kroute = {};
+int virq;
+
+if (!kvm_gsi_routing_enabled()) {
+return -ENOSYS;
+}
+if (!kvm_check_extension(s, KVM_CAP_HYPERV_SYNIC)) {
+return -ENOSYS;
+}
+virq = kvm_irqchip_get_virq(s);
+if (virq < 0) {
+return virq;
+}
+
+kroute.gsi = virq;
+kroute.type = KVM_IRQ_ROUTING_HV_SINT;
+kroute.flags = 0;
+kroute.u.hv_sint.vcpu = vcpu;
+kroute.u.hv_sint.sint = sint;
+
+kvm_add_routing_entry(s, &kroute);
+kvm_irqchip_commit_routes(s);
+
+return virq;
+}
+
 #else /* !KVM_CAP_IRQ_ROUTING */
 
 void kvm_init_irq_routing(KVMState *s)
@@ -1322,6 +1350,11 @@ int kvm_irqchip_add_adapter_route(KVMState *s, 
AdapterInfo *adapter)
 return -ENOSYS;
 }
 
+int kvm_irqchip_add_hv_sint_route(KVMState *s, uint32_t vcpu, uint32_t sint)
+{
+return -ENOSYS;
+}
+
 static int kvm_irqchip_assign_irqfd(KVMState *s, int fd, int virq, bool assign)
 {
 abort();
-- 
2.4.3




[Qemu-devel] [PATCH v2 0/5] QEMU: Hyper-V SynIC support

2015-11-10 Thread Andrey Smetanin
Hyper-V SynIC (synthetic interrupt controller) support:
* msr's support
* irq routing setup
* irq injection
* irq ack's callbacks
* event/message pages changes tracking at Hyper-V exit
* Hyper-V test device to test SynIC by kvm-unit-tests

Signed-off-by: Andrey Smetanin 
Reviewed-by: Roman Kagan 
Signed-off-by: Denis V. Lunev 
CC: Paolo Bonzini 
CC: Richard Henderson 
CC: Eduardo Habkost 
CC: "Andreas Färber" 
CC: Marcelo Tosatti 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: k...@vger.kernel.org

Changes v2:
* linux headers update by scripts moved into separate patche
* activate Hyper-V SynIC by enabling corresponding vcpu cap
* reject cpu initialization if user requested Hyper-V SynIC
  but kernel does not support Hyper-V SynIC

Andrey Smetanin (5):
  headers: Linux kernel Hyper-V SynIC defines
  target-i386/kvm: Hyper-V SynIC MSR's support
  kvm: Hyper-V SynIC irq routing support
  target-i386/hyperv: Hyper-V SynIC SINT routing and vcpu exit
  hw/misc: Hyper-V test device 'hyperv-testdev'

 default-configs/i386-softmmu.mak  |   1 +
 default-configs/x86_64-softmmu.mak|   1 +
 hw/misc/Makefile.objs |   1 +
 hw/misc/hyperv_testdev.c  | 164 ++
 include/standard-headers/asm-x86/hyperv.h |  12 +++
 include/sysemu/kvm.h  |   1 +
 kvm-all.c |  33 ++
 linux-headers/linux/kvm.h |  25 +
 target-i386/Makefile.objs |   2 +-
 target-i386/cpu-qom.h |   1 +
 target-i386/cpu.c |   1 +
 target-i386/cpu.h |   5 +
 target-i386/hyperv.c  | 127 +++
 target-i386/hyperv.h  |  42 
 target-i386/kvm.c |  73 -
 target-i386/machine.c |  39 +++
 16 files changed, 526 insertions(+), 2 deletions(-)
 create mode 100644 hw/misc/hyperv_testdev.c
 create mode 100644 target-i386/hyperv.c
 create mode 100644 target-i386/hyperv.h

-- 
2.4.3




[Qemu-devel] [PATCH v4 0/5] KVM: Hyper-V synthetic interrupt controller

2015-11-10 Thread Andrey Smetanin
This patchset implements the KVM part of the synthetic interrupt
controller (SynIC) which is a building block of the Hyper-V
paravirtualized device bus (vmbus).

SynIC is a lapic extension, which is controlled via MSRs and maintains
for each vCPU
 - 16 synthetic interrupt "lines" (SINT's); each can be configured to
   trigger a specific interrupt vector optionally with auto-EOI
   semantics
 - a message page in the guest memory with 16 256-byte per-SINT message
   slots
 - an event flag page in the guest memory with 16 2048-bit per-SINT
   event flag areas

The host triggers a SINT whenever it delivers a new message to the
corresponding slot or flips an event flag bit in the corresponding area.
The guest informs the host that it can try delivering a message by
explicitly asserting EOI in lapic or writing to End-Of-Message (EOM)
MSR.

The userspace (qemu) triggers interrupts and receives EOM notifications
via irqfd with resampler; for that, a GSI is allocated for each
configured SINT, and irq_routing api is extended to support GSI-SINT
mapping.

Besides, a new vcpu exit is introduced to notify the userspace of the
changes in SynIC configuraion triggered by guest writing to the
corresponding MSRs.

Since auto-EOI behavior of SynIC cannot be made compatible with APIC
hardware virtualization, the latter is disabled using a newly
introduced flag, when SynIC is activated.

This patches seria has been tested by running of kvm-unit-tests
(which also includes previosly sent 'hyperv_synic' test) with
host CPU which supports APICv (Intel(R) Xeon(R) CPU E5-2407 v2 @ 2.40GHz)

Signed-off-by: Andrey Smetanin 
Reviewed-by: Roman Kagan 
Signed-off-by: Denis V. Lunev 
CC: Gleb Natapov 
CC: Paolo Bonzini 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: qemu-devel@nongnu.org

Changes v4:
* disable APICv in case Hyper-V SynIC enabled
* patchset rebase into latest kvm/queue (10 Nov 2015)
* do Hyper-V SynIC exit only at !host(guest) msr's writes

Changes v3:
* Hyper-V SynIC KVM API documentation fixes

Changes v2:
* irqchip/eventfd preparation improvements to support
arch specific routing entries like Hyper-V SynIC.
* add Hyper-V SynIC vectors into EOI exit bitmap.
* do not use posted interrupts in case of Hyper-V SynIC
AutoEOI vectors

Andrey Smetanin (5):
  kvm/irqchip: kvm_arch_irq_routing_update renaming split
  kvm/x86: split ioapic-handled and EOI exit bitmaps
  kvm/x86: per-vcpu apicv deactivation support
  kvm/x86: Hyper-V synthetic interrupt controller
  kvm/x86: Hyper-V kvm exit

 Documentation/virtual/kvm/api.txt |  41 +
 arch/x86/include/asm/kvm_host.h   |  26 ++-
 arch/x86/kvm/hyperv.c | 335 ++
 arch/x86/kvm/hyperv.h |  23 +++
 arch/x86/kvm/ioapic.c |   4 +-
 arch/x86/kvm/ioapic.h |   7 +-
 arch/x86/kvm/irq.c|   2 +-
 arch/x86/kvm/irq_comm.c   |  41 -
 arch/x86/kvm/lapic.c  |  40 +++--
 arch/x86/kvm/lapic.h  |   9 +-
 arch/x86/kvm/svm.c|  13 +-
 arch/x86/kvm/vmx.c|  48 +++---
 arch/x86/kvm/x86.c|  66 +++-
 include/linux/kvm_host.h  |  12 +-
 include/uapi/linux/kvm.h  |  25 +++
 virt/kvm/irqchip.c|   7 +-
 16 files changed, 625 insertions(+), 74 deletions(-)

-- 
2.4.3




[Qemu-devel] [PATCH v4 1/5] kvm/irqchip: kvm_arch_irq_routing_update renaming split

2015-11-10 Thread Andrey Smetanin
Actually kvm_arch_irq_routing_update() should be
kvm_arch_post_irq_routing_update() as it's called at the end
of irq routing update.

This renaming frees kvm_arch_irq_routing_update function name.
kvm_arch_irq_routing_update() weak function which will be used
to update mappings for arch-specific irq routing entries
(in particular, the upcoming Hyper-V synthetic interrupts).

Signed-off-by: Andrey Smetanin 
Reviewed-by: Roman Kagan 
Signed-off-by: Denis V. Lunev 
CC: Gleb Natapov 
CC: Paolo Bonzini 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: qemu-devel@nongnu.org

---
 arch/x86/kvm/irq_comm.c  | 2 +-
 include/linux/kvm_host.h | 5 +++--
 virt/kvm/irqchip.c   | 7 ++-
 3 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kvm/irq_comm.c b/arch/x86/kvm/irq_comm.c
index 84b96d3..e39768c 100644
--- a/arch/x86/kvm/irq_comm.c
+++ b/arch/x86/kvm/irq_comm.c
@@ -332,7 +332,7 @@ int kvm_setup_empty_irq_routing(struct kvm *kvm)
return kvm_set_irq_routing(kvm, empty_routing, 0, 0);
 }
 
-void kvm_arch_irq_routing_update(struct kvm *kvm)
+void kvm_arch_post_irq_routing_update(struct kvm *kvm)
 {
if (ioapic_in_kernel(kvm) || !irqchip_in_kernel(kvm))
return;
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 242a6d2..dbe2a2f 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -473,12 +473,12 @@ void vcpu_put(struct kvm_vcpu *vcpu);
 
 #ifdef __KVM_HAVE_IOAPIC
 void kvm_vcpu_request_scan_ioapic(struct kvm *kvm);
-void kvm_arch_irq_routing_update(struct kvm *kvm);
+void kvm_arch_post_irq_routing_update(struct kvm *kvm);
 #else
 static inline void kvm_vcpu_request_scan_ioapic(struct kvm *kvm)
 {
 }
-static inline void kvm_arch_irq_routing_update(struct kvm *kvm)
+static inline void kvm_arch_post_irq_routing_update(struct kvm *kvm)
 {
 }
 #endif
@@ -1080,6 +1080,7 @@ static inline void kvm_irq_routing_update(struct kvm *kvm)
 {
 }
 #endif
+void kvm_arch_irq_routing_update(struct kvm *kvm);
 
 static inline int kvm_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
 {
diff --git a/virt/kvm/irqchip.c b/virt/kvm/irqchip.c
index f0b08a2..fe84e1a 100644
--- a/virt/kvm/irqchip.c
+++ b/virt/kvm/irqchip.c
@@ -166,6 +166,10 @@ out:
return r;
 }
 
+void __attribute__((weak)) kvm_arch_irq_routing_update(struct kvm *kvm)
+{
+}
+
 int kvm_set_irq_routing(struct kvm *kvm,
const struct kvm_irq_routing_entry *ue,
unsigned nr,
@@ -219,9 +223,10 @@ int kvm_set_irq_routing(struct kvm *kvm,
old = kvm->irq_routing;
rcu_assign_pointer(kvm->irq_routing, new);
kvm_irq_routing_update(kvm);
+   kvm_arch_irq_routing_update(kvm);
mutex_unlock(&kvm->irq_lock);
 
-   kvm_arch_irq_routing_update(kvm);
+   kvm_arch_post_irq_routing_update(kvm);
 
synchronize_srcu_expedited(&kvm->irq_srcu);
 
-- 
2.4.3




[Qemu-devel] [PATCH v2 1/5] headers: Linux kernel Hyper-V SynIC defines

2015-11-10 Thread Andrey Smetanin
This patch brings in the necessary changes from the corresponding kernel
patchset.  It's included only for completeness; ideally these changes
should arrive via the standard kernel header pull.

Signed-off-by: Andrey Smetanin 
Reviewed-by: Roman Kagan 
Signed-off-by: Denis V. Lunev 
CC: Paolo Bonzini 
CC: Richard Henderson 
CC: Eduardo Habkost 
CC: "Andreas Färber" 
CC: Marcelo Tosatti 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: k...@vger.kernel.org

---
 include/standard-headers/asm-x86/hyperv.h | 12 
 linux-headers/linux/kvm.h | 25 +
 2 files changed, 37 insertions(+)

diff --git a/include/standard-headers/asm-x86/hyperv.h 
b/include/standard-headers/asm-x86/hyperv.h
index c37c14e..f9780f1 100644
--- a/include/standard-headers/asm-x86/hyperv.h
+++ b/include/standard-headers/asm-x86/hyperv.h
@@ -257,4 +257,16 @@ typedef struct _HV_REFERENCE_TSC_PAGE {
int64_t tsc_offset;
 } HV_REFERENCE_TSC_PAGE, *PHV_REFERENCE_TSC_PAGE;
 
+/* Define the number of synthetic interrupt sources. */
+#define HV_SYNIC_SINT_COUNT(16)
+/* Define the expected SynIC version. */
+#define HV_SYNIC_VERSION_1 (0x1)
+
+#define HV_SYNIC_CONTROL_ENABLE(1ULL << 0)
+#define HV_SYNIC_SIMP_ENABLE   (1ULL << 0)
+#define HV_SYNIC_SIEFP_ENABLE  (1ULL << 0)
+#define HV_SYNIC_SINT_MASKED   (1ULL << 16)
+#define HV_SYNIC_SINT_AUTO_EOI (1ULL << 17)
+#define HV_SYNIC_SINT_VECTOR_MASK  (0xFF)
+
 #endif
diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
index dcc410e..4e20262 100644
--- a/linux-headers/linux/kvm.h
+++ b/linux-headers/linux/kvm.h
@@ -154,6 +154,20 @@ struct kvm_s390_skeys {
__u32 flags;
__u32 reserved[9];
 };
+
+struct kvm_hyperv_exit {
+#define KVM_EXIT_HYPERV_SYNIC  1
+   __u32 type;
+   union {
+   struct {
+   __u32 msr;
+   __u64 control;
+   __u64 evt_page;
+   __u64 msg_page;
+   } synic;
+   } u;
+};
+
 #define KVM_S390_GET_SKEYS_NONE   1
 #define KVM_S390_SKEYS_MAX1048576
 
@@ -184,6 +198,7 @@ struct kvm_s390_skeys {
 #define KVM_EXIT_SYSTEM_EVENT 24
 #define KVM_EXIT_S390_STSI25
 #define KVM_EXIT_IOAPIC_EOI   26
+#define KVM_EXIT_HYPERV   27
 
 /* For KVM_EXIT_INTERNAL_ERROR */
 /* Emulate instruction failed. */
@@ -338,6 +353,8 @@ struct kvm_run {
struct {
__u8 vector;
} eoi;
+   /* KVM_EXIT_HYPERV */
+   struct kvm_hyperv_exit hyperv;
/* Fix the size of the union. */
char padding[256];
};
@@ -831,6 +848,7 @@ struct kvm_ppc_smmu_info {
 #define KVM_CAP_GUEST_DEBUG_HW_WPS 120
 #define KVM_CAP_SPLIT_IRQCHIP 121
 #define KVM_CAP_IOEVENTFD_ANY_LENGTH 122
+#define KVM_CAP_HYPERV_SYNIC 123
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
@@ -854,10 +872,16 @@ struct kvm_irq_routing_s390_adapter {
__u32 adapter_id;
 };
 
+struct kvm_irq_routing_hv_sint {
+   __u32 vcpu;
+   __u32 sint;
+};
+
 /* gsi routing entry types */
 #define KVM_IRQ_ROUTING_IRQCHIP 1
 #define KVM_IRQ_ROUTING_MSI 2
 #define KVM_IRQ_ROUTING_S390_ADAPTER 3
+#define KVM_IRQ_ROUTING_HV_SINT 4
 
 struct kvm_irq_routing_entry {
__u32 gsi;
@@ -868,6 +892,7 @@ struct kvm_irq_routing_entry {
struct kvm_irq_routing_irqchip irqchip;
struct kvm_irq_routing_msi msi;
struct kvm_irq_routing_s390_adapter adapter;
+   struct kvm_irq_routing_hv_sint hv_sint;
__u32 pad[8];
} u;
 };
-- 
2.4.3




[Qemu-devel] [PATCH v2 4/5] target-i386/hyperv: Hyper-V SynIC SINT routing and vcpu exit

2015-11-10 Thread Andrey Smetanin
Hyper-V SynIC(synthetic interrupt controller) helpers for
Hyper-V SynIC irq routing setup, irq injection, irq ack
notifications event/message pages changes tracking for future use.

Signed-off-by: Andrey Smetanin 
Reviewed-by: Roman Kagan 
Signed-off-by: Denis V. Lunev 
CC: Paolo Bonzini 
CC: Richard Henderson 
CC: Eduardo Habkost 
CC: "Andreas Färber" 
CC: Marcelo Tosatti 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: k...@vger.kernel.org

---
 target-i386/Makefile.objs |   2 +-
 target-i386/hyperv.c  | 127 ++
 target-i386/hyperv.h  |  42 +++
 target-i386/kvm.c |   6 +++
 4 files changed, 176 insertions(+), 1 deletion(-)
 create mode 100644 target-i386/hyperv.c
 create mode 100644 target-i386/hyperv.h

diff --git a/target-i386/Makefile.objs b/target-i386/Makefile.objs
index 437d997..2255f46 100644
--- a/target-i386/Makefile.objs
+++ b/target-i386/Makefile.objs
@@ -3,5 +3,5 @@ obj-y += excp_helper.o fpu_helper.o cc_helper.o int_helper.o 
svm_helper.o
 obj-y += smm_helper.o misc_helper.o mem_helper.o seg_helper.o
 obj-y += gdbstub.o
 obj-$(CONFIG_SOFTMMU) += machine.o arch_memory_mapping.o arch_dump.o monitor.o
-obj-$(CONFIG_KVM) += kvm.o
+obj-$(CONFIG_KVM) += kvm.o hyperv.o
 obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
diff --git a/target-i386/hyperv.c b/target-i386/hyperv.c
new file mode 100644
index 000..e79b173
--- /dev/null
+++ b/target-i386/hyperv.c
@@ -0,0 +1,127 @@
+/*
+ * QEMU KVM Hyper-V support
+ *
+ * Copyright (C) 2015 Andrey Smetanin 
+ *
+ * Authors:
+ *  Andrey Smetanin 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include "hyperv.h"
+#include "standard-headers/asm-x86/hyperv.h"
+
+int kvm_hv_handle_exit(X86CPU *cpu, struct kvm_hyperv_exit *exit)
+{
+CPUX86State *env = &cpu->env;
+
+switch (exit->type) {
+case KVM_EXIT_HYPERV_SYNIC:
+if (!cpu->hyperv_synic) {
+return -1;
+}
+
+/*
+ * For now just track changes in SynIC control and msg/evt pages msr's.
+ * When SynIC messaging/events processing will be added in future
+ * here we will do messages queues flushing and pages remapping.
+ */
+switch (exit->u.synic.msr) {
+case HV_X64_MSR_SCONTROL:
+env->msr_hv_synic_control = exit->u.synic.control;
+break;
+case HV_X64_MSR_SIMP:
+env->msr_hv_synic_msg_page = exit->u.synic.msg_page;
+break;
+case HV_X64_MSR_SIEFP:
+env->msr_hv_synic_evt_page = exit->u.synic.evt_page;
+break;
+default:
+return -1;
+}
+return 0;
+default:
+return -1;
+}
+}
+
+static void kvm_hv_sint_ack_handler(EventNotifier *notifier)
+{
+HvSintRoute *sint_route = container_of(notifier, HvSintRoute,
+   sint_ack_notifier);
+event_notifier_test_and_clear(notifier);
+if (sint_route->sint_ack_clb) {
+sint_route->sint_ack_clb(sint_route);
+}
+}
+
+HvSintRoute *kvm_hv_sint_route_create(uint32_t vcpu_id, uint32_t sint,
+  HvSintAckClb sint_ack_clb)
+{
+HvSintRoute *sint_route;
+int r, gsi;
+
+sint_route = g_malloc0(sizeof(*sint_route));
+r = event_notifier_init(&sint_route->sint_set_notifier, false);
+if (r) {
+goto err;
+}
+
+r = event_notifier_init(&sint_route->sint_ack_notifier, false);
+if (r) {
+goto err_sint_set_notifier;
+}
+
+event_notifier_set_handler(&sint_route->sint_ack_notifier,
+   kvm_hv_sint_ack_handler);
+
+gsi = kvm_irqchip_add_hv_sint_route(kvm_state, vcpu_id, sint);
+if (gsi < 0) {
+goto err_gsi;
+}
+
+r = kvm_irqchip_add_irqfd_notifier_gsi(kvm_state,
+   &sint_route->sint_set_notifier,
+   &sint_route->sint_ack_notifier, 
gsi);
+if (r) {
+goto err_irqfd;
+}
+sint_route->gsi = gsi;
+sint_route->sint_ack_clb = sint_ack_clb;
+sint_route->vcpu_id = vcpu_id;
+sint_route->sint = sint;
+
+return sint_route;
+
+err_irqfd:
+kvm_irqchip_release_virq(kvm_state, gsi);
+err_gsi:
+event_notifier_set_handler(&sint_route->sint_ack_notifier, NULL);
+event_notifier_cleanup(&sint_route->sint_ack_notifier);
+err_sint_set_notifier:
+event_notifier_cleanup(&sint_route->sint_set_notifier);
+err:
+g_free(sint_route);
+
+return NULL;
+}
+
+void kvm_hv_sint_route_destroy(HvSintRoute *sint_route)
+{
+kvm_irqchip_remove_irqfd_notifier_gsi(kvm_state,
+  &sint_route->sint_set_notifier,
+ 

[Qemu-devel] [PATCH v4 2/5] kvm/x86: split ioapic-handled and EOI exit bitmaps

2015-11-10 Thread Andrey Smetanin
The function to determine if the vector is handled by ioapic used to
rely on the fact that only ioapic-handled vectors were set up to
cause vmexits when virtual apic was in use.

We're going to break this assumption when introducing Hyper-V
synthetic interrupts: they may need to cause vmexits too.

To achieve that, introduce a new bitmap dedicated specifically for
ioapic-handled vectors, and populate EOI exit bitmap from it for now.

Signed-off-by: Andrey Smetanin 
Reviewed-by: Roman Kagan 
Signed-off-by: Denis V. Lunev 
CC: Gleb Natapov 
CC: Paolo Bonzini 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: qemu-devel@nongnu.org

---
 arch/x86/include/asm/kvm_host.h |  4 ++--
 arch/x86/kvm/ioapic.c   |  4 ++--
 arch/x86/kvm/ioapic.h   |  7 ---
 arch/x86/kvm/irq_comm.c |  5 +++--
 arch/x86/kvm/lapic.c|  2 +-
 arch/x86/kvm/svm.c  |  2 +-
 arch/x86/kvm/vmx.c  |  3 +--
 arch/x86/kvm/x86.c  | 11 ++-
 8 files changed, 20 insertions(+), 18 deletions(-)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 9265196..d51a7e1d 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -400,7 +400,7 @@ struct kvm_vcpu_arch {
u64 efer;
u64 apic_base;
struct kvm_lapic *apic;/* kernel irqchip context */
-   u64 eoi_exit_bitmap[4];
+   DECLARE_BITMAP(ioapic_handled_vectors, 256);
unsigned long apic_attention;
int32_t apic_arb_prio;
int mp_state;
@@ -833,7 +833,7 @@ struct kvm_x86_ops {
int (*cpu_uses_apicv)(struct kvm_vcpu *vcpu);
void (*hwapic_irr_update)(struct kvm_vcpu *vcpu, int max_irr);
void (*hwapic_isr_update)(struct kvm *kvm, int isr);
-   void (*load_eoi_exitmap)(struct kvm_vcpu *vcpu);
+   void (*load_eoi_exitmap)(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap);
void (*set_virtual_x2apic_mode)(struct kvm_vcpu *vcpu, bool set);
void (*set_apic_access_page_addr)(struct kvm_vcpu *vcpu, hpa_t hpa);
void (*deliver_posted_interrupt)(struct kvm_vcpu *vcpu, int vector);
diff --git a/arch/x86/kvm/ioapic.c b/arch/x86/kvm/ioapic.c
index 88d0a92..1facfd6 100644
--- a/arch/x86/kvm/ioapic.c
+++ b/arch/x86/kvm/ioapic.c
@@ -233,7 +233,7 @@ static void kvm_ioapic_inject_all(struct kvm_ioapic 
*ioapic, unsigned long irr)
 }
 
 
-void kvm_ioapic_scan_entry(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap)
+void kvm_ioapic_scan_entry(struct kvm_vcpu *vcpu, ulong 
*ioapic_handled_vectors)
 {
struct kvm_ioapic *ioapic = vcpu->kvm->arch.vioapic;
union kvm_ioapic_redirect_entry *e;
@@ -250,7 +250,7 @@ void kvm_ioapic_scan_entry(struct kvm_vcpu *vcpu, u64 
*eoi_exit_bitmap)
(e->fields.trig_mode == IOAPIC_EDGE_TRIG &&
 kvm_apic_pending_eoi(vcpu, e->fields.vector)))
__set_bit(e->fields.vector,
-   (unsigned long *)eoi_exit_bitmap);
+ ioapic_handled_vectors);
}
}
spin_unlock(&ioapic->lock);
diff --git a/arch/x86/kvm/ioapic.h b/arch/x86/kvm/ioapic.h
index 084617d..2d16dc2 100644
--- a/arch/x86/kvm/ioapic.h
+++ b/arch/x86/kvm/ioapic.h
@@ -121,7 +121,8 @@ int kvm_irq_delivery_to_apic(struct kvm *kvm, struct 
kvm_lapic *src,
struct kvm_lapic_irq *irq, unsigned long *dest_map);
 int kvm_get_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state);
 int kvm_set_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state);
-void kvm_ioapic_scan_entry(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap);
-void kvm_scan_ioapic_routes(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap);
-
+void kvm_ioapic_scan_entry(struct kvm_vcpu *vcpu,
+  ulong *ioapic_handled_vectors);
+void kvm_scan_ioapic_routes(struct kvm_vcpu *vcpu,
+   ulong *ioapic_handled_vectors);
 #endif
diff --git a/arch/x86/kvm/irq_comm.c b/arch/x86/kvm/irq_comm.c
index e39768c..ece901c 100644
--- a/arch/x86/kvm/irq_comm.c
+++ b/arch/x86/kvm/irq_comm.c
@@ -339,7 +339,8 @@ void kvm_arch_post_irq_routing_update(struct kvm *kvm)
kvm_make_scan_ioapic_request(kvm);
 }
 
-void kvm_scan_ioapic_routes(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap)
+void kvm_scan_ioapic_routes(struct kvm_vcpu *vcpu,
+   ulong *ioapic_handled_vectors)
 {
struct kvm *kvm = vcpu->kvm;
struct kvm_kernel_irq_routing_entry *entry;
@@ -369,7 +370,7 @@ void kvm_scan_ioapic_routes(struct kvm_vcpu *vcpu, u64 
*eoi_exit_bitmap)
u32 vector = entry->msi.data & 0xff;
 
__set_bit(vector,
- (unsigned long *) eoi_exit_bitmap);
+ ioapic_handled_vectors);
}
}
}

[Qemu-devel] [PATCH v2 5/5] hw/misc: Hyper-V test device 'hyperv-testdev'

2015-11-10 Thread Andrey Smetanin
'hyperv-testdev' will be used by kvm-unit-tests
to setup Hyper-V SynIC SINT's routing and to inject
Hyper-V SynIC SINT's.

Hyper-V test device is ISA type device that creates 0x3000
IO memory region and catches write access into it. Every
write operation data decoded into ctl code and parameters
for Hyper-V test device.

Signed-off-by: Andrey Smetanin 
Reviewed-by: Roman Kagan 
Signed-off-by: Denis V. Lunev 
CC: Paolo Bonzini 
CC: Richard Henderson 
CC: Eduardo Habkost 
CC: "Andreas Färber" 
CC: Marcelo Tosatti 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: k...@vger.kernel.org

---
 default-configs/i386-softmmu.mak   |   1 +
 default-configs/x86_64-softmmu.mak |   1 +
 hw/misc/Makefile.objs  |   1 +
 hw/misc/hyperv_testdev.c   | 164 +
 4 files changed, 167 insertions(+)
 create mode 100644 hw/misc/hyperv_testdev.c

diff --git a/default-configs/i386-softmmu.mak b/default-configs/i386-softmmu.mak
index 43c96d1..7f3c850 100644
--- a/default-configs/i386-softmmu.mak
+++ b/default-configs/i386-softmmu.mak
@@ -50,3 +50,4 @@ CONFIG_XIO3130=y
 CONFIG_IOH3420=y
 CONFIG_I82801B11=y
 CONFIG_SMBIOS=y
+CONFIG_HYPERV_TESTDEV=y
diff --git a/default-configs/x86_64-softmmu.mak 
b/default-configs/x86_64-softmmu.mak
index dfb8095..e494d79 100644
--- a/default-configs/x86_64-softmmu.mak
+++ b/default-configs/x86_64-softmmu.mak
@@ -50,3 +50,4 @@ CONFIG_XIO3130=y
 CONFIG_IOH3420=y
 CONFIG_I82801B11=y
 CONFIG_SMBIOS=y
+CONFIG_HYPERV_TESTDEV=y
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index 4aa76ff..fafc80a 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -40,3 +40,4 @@ obj-$(CONFIG_STM32F2XX_SYSCFG) += stm32f2xx_syscfg.o
 
 obj-$(CONFIG_PVPANIC) += pvpanic.o
 obj-$(CONFIG_EDU) += edu.o
+obj-$(CONFIG_HYPERV_TESTDEV) += hyperv_testdev.o
diff --git a/hw/misc/hyperv_testdev.c b/hw/misc/hyperv_testdev.c
new file mode 100644
index 000..f0e4e35
--- /dev/null
+++ b/hw/misc/hyperv_testdev.c
@@ -0,0 +1,164 @@
+/*
+ * QEMU KVM Hyper-V test device to support Hyper-V kvm-unit-tests
+ *
+ * Copyright (C) 2015 Andrey Smetanin 
+ *
+ * Authors:
+ *  Andrey Smetanin 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include "hw/hw.h"
+#include "hw/qdev.h"
+#include "hw/isa/isa.h"
+#include "target-i386/hyperv.h"
+
+#define HV_TEST_DEV_MAX_SINT_ROUTES 64
+
+struct HypervTestDev {
+ISADevice parent_obj;
+MemoryRegion sint_control;
+HvSintRoute *sint_route[HV_TEST_DEV_MAX_SINT_ROUTES];
+};
+typedef struct HypervTestDev HypervTestDev;
+
+#define TYPE_HYPERV_TEST_DEV "hyperv-testdev"
+#define HYPERV_TEST_DEV(obj) \
+OBJECT_CHECK(HypervTestDev, (obj), TYPE_HYPERV_TEST_DEV)
+
+enum {
+HV_TEST_DEV_SINT_ROUTE_CREATE = 1,
+HV_TEST_DEV_SINT_ROUTE_DESTROY,
+HV_TEST_DEV_SINT_ROUTE_SET_SINT
+};
+
+static int alloc_sint_route_index(HypervTestDev *dev)
+{
+int i;
+
+for (i = 0; i < ARRAY_SIZE(dev->sint_route); i++) {
+if (dev->sint_route[i] == NULL) {
+return i;
+}
+}
+return -1;
+}
+
+static void free_sint_route_index(HypervTestDev *dev, int i)
+{
+assert(i >= 0 && i < ARRAY_SIZE(dev->sint_route));
+dev->sint_route[i] = NULL;
+}
+
+static int find_sint_route_index(HypervTestDev *dev, uint32_t vcpu_id,
+ uint32_t sint)
+{
+HvSintRoute *sint_route;
+int i;
+
+for (i = 0; i < ARRAY_SIZE(dev->sint_route); i++) {
+sint_route = dev->sint_route[i];
+if (sint_route && sint_route->vcpu_id == vcpu_id &&
+sint_route->sint == sint) {
+return i;
+}
+}
+return -1;
+}
+
+static void hv_synic_test_dev_control(HypervTestDev *dev, uint32_t ctl,
+  uint32_t vcpu_id, uint32_t sint)
+{
+int i;
+HvSintRoute *sint_route;
+
+switch (ctl) {
+case HV_TEST_DEV_SINT_ROUTE_CREATE:
+i = alloc_sint_route_index(dev);
+assert(i >= 0);
+sint_route = kvm_hv_sint_route_create(vcpu_id, sint, NULL);
+assert(sint_route);
+dev->sint_route[i] = sint_route;
+break;
+case HV_TEST_DEV_SINT_ROUTE_DESTROY:
+i = find_sint_route_index(dev, vcpu_id, sint);
+assert(i >= 0);
+sint_route = dev->sint_route[i];
+kvm_hv_sint_route_destroy(sint_route);
+free_sint_route_index(dev, i);
+break;
+case HV_TEST_DEV_SINT_ROUTE_SET_SINT:
+i = find_sint_route_index(dev, vcpu_id, sint);
+assert(i >= 0);
+sint_route = dev->sint_route[i];
+kvm_hv_sint_route_set_sint(sint_route);
+break;
+default:
+break;
+}
+}
+
+static void hv_test_dev_control(void *opaque, hwaddr addr, uint64_t data,
+

[Qemu-devel] [PATCH v4 3/5] kvm/x86: per-vcpu apicv deactivation support

2015-11-10 Thread Andrey Smetanin
The decision on whether to use hardware APIC virtualization used to be
taken globally, based on the availability of the feature in the CPU
and the value of a module parameter.

However, under certain circumstances we want to control it on per-vcpu
basis.  In particular, when the userspace activates HyperV synthetic
interrupt controller (SynIC), APICv has to be disabled as it's
incompatible with SynIC auto-EOI behavior.

To achieve that, introduce 'apicv_active' flag on struct
kvm_vcpu_arch, and kvm_vcpu_deactivate_apicv() function to turn APICv
off.  The flag is initialized based on the module parameter and CPU
capability, and consulted whenever an APICv-specific action is
performed.

Signed-off-by: Andrey Smetanin 
Reviewed-by: Roman Kagan 
Signed-off-by: Denis V. Lunev 
CC: Gleb Natapov 
CC: Paolo Bonzini 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: qemu-devel@nongnu.org

---
 arch/x86/include/asm/kvm_host.h |  6 +-
 arch/x86/kvm/irq.c  |  2 +-
 arch/x86/kvm/lapic.c| 23 +++--
 arch/x86/kvm/lapic.h|  4 ++--
 arch/x86/kvm/svm.c  | 11 +++---
 arch/x86/kvm/vmx.c  | 45 +
 arch/x86/kvm/x86.c  | 19 ++---
 7 files changed, 63 insertions(+), 47 deletions(-)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index d51a7e1d..a60a461 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -400,6 +400,7 @@ struct kvm_vcpu_arch {
u64 efer;
u64 apic_base;
struct kvm_lapic *apic;/* kernel irqchip context */
+   bool apicv_active;
DECLARE_BITMAP(ioapic_handled_vectors, 256);
unsigned long apic_attention;
int32_t apic_arb_prio;
@@ -830,7 +831,8 @@ struct kvm_x86_ops {
void (*enable_nmi_window)(struct kvm_vcpu *vcpu);
void (*enable_irq_window)(struct kvm_vcpu *vcpu);
void (*update_cr8_intercept)(struct kvm_vcpu *vcpu, int tpr, int irr);
-   int (*cpu_uses_apicv)(struct kvm_vcpu *vcpu);
+   bool (*get_enable_apicv)(void);
+   void (*refresh_apicv_exec_ctrl)(struct kvm_vcpu *vcpu);
void (*hwapic_irr_update)(struct kvm_vcpu *vcpu, int max_irr);
void (*hwapic_isr_update)(struct kvm *kvm, int isr);
void (*load_eoi_exitmap)(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap);
@@ -1096,6 +1098,8 @@ gpa_t kvm_mmu_gva_to_gpa_write(struct kvm_vcpu *vcpu, 
gva_t gva,
 gpa_t kvm_mmu_gva_to_gpa_system(struct kvm_vcpu *vcpu, gva_t gva,
struct x86_exception *exception);
 
+void kvm_vcpu_deactivate_apicv(struct kvm_vcpu *vcpu);
+
 int kvm_emulate_hypercall(struct kvm_vcpu *vcpu);
 
 int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t gva, u32 error_code,
diff --git a/arch/x86/kvm/irq.c b/arch/x86/kvm/irq.c
index 097060e..3982b47 100644
--- a/arch/x86/kvm/irq.c
+++ b/arch/x86/kvm/irq.c
@@ -76,7 +76,7 @@ int kvm_cpu_has_injectable_intr(struct kvm_vcpu *v)
if (kvm_cpu_has_extint(v))
return 1;
 
-   if (kvm_vcpu_apic_vid_enabled(v))
+   if (kvm_vcpu_apicv_active(v))
return 0;
 
return kvm_apic_has_interrupt(v) != -1; /* LAPIC */
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index b14436d..14d6fcc 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -379,7 +379,8 @@ static inline int apic_find_highest_irr(struct kvm_lapic 
*apic)
if (!apic->irr_pending)
return -1;
 
-   kvm_x86_ops->sync_pir_to_irr(apic->vcpu);
+   if (apic->vcpu->arch.apicv_active)
+   kvm_x86_ops->sync_pir_to_irr(apic->vcpu);
result = apic_search_irr(apic);
ASSERT(result == -1 || result >= 16);
 
@@ -392,7 +393,7 @@ static inline void apic_clear_irr(int vec, struct kvm_lapic 
*apic)
 
vcpu = apic->vcpu;
 
-   if (unlikely(kvm_vcpu_apic_vid_enabled(vcpu))) {
+   if (unlikely(vcpu->arch.apicv_active)) {
/* try to update RVI */
apic_clear_vector(vec, apic->regs + APIC_IRR);
kvm_make_request(KVM_REQ_EVENT, vcpu);
@@ -418,7 +419,7 @@ static inline void apic_set_isr(int vec, struct kvm_lapic 
*apic)
 * because the processor can modify ISR under the hood.  Instead
 * just set SVI.
 */
-   if (unlikely(kvm_x86_ops->hwapic_isr_update))
+   if (unlikely(vcpu->arch.apicv_active))
kvm_x86_ops->hwapic_isr_update(vcpu->kvm, vec);
else {
++apic->isr_count;
@@ -466,7 +467,7 @@ static inline void apic_clear_isr(int vec, struct kvm_lapic 
*apic)
 * on the other hand isr_count and highest_isr_cache are unused
 * and must be left alone.
 */
-   if (unlikely(kvm_x86_ops->hwapic_isr_update))
+   if (unlikely(vcpu->arch.ap

[Qemu-devel] [PATCH v2 2/5] target-i386/kvm: Hyper-V SynIC MSR's support

2015-11-10 Thread Andrey Smetanin
This patch does Hyper-V Synthetic interrupt
controller(Hyper-V SynIC) MSR's support and
migration. Hyper-V SynIC is enabled by cpu's
'hv-synic' option.

This patch does not allow cpu creation if
'hv-synic' option specified but kernel
doesn't support Hyper-V SynIC.

Changes v2:
* activate Hyper-V SynIC by enabling corresponding vcpu cap
* reject cpu initialization if user requested Hyper-V SynIC
  but kernel does not support Hyper-V SynIC

Signed-off-by: Andrey Smetanin 
Reviewed-by: Roman Kagan 
Signed-off-by: Denis V. Lunev 
CC: Paolo Bonzini 
CC: Richard Henderson 
CC: Eduardo Habkost 
CC: "Andreas Färber" 
CC: Marcelo Tosatti 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: k...@vger.kernel.org

---
 target-i386/cpu-qom.h |  1 +
 target-i386/cpu.c |  1 +
 target-i386/cpu.h |  5 
 target-i386/kvm.c | 67 ++-
 target-i386/machine.c | 39 ++
 5 files changed, 112 insertions(+), 1 deletion(-)

diff --git a/target-i386/cpu-qom.h b/target-i386/cpu-qom.h
index e3bfe9d..7ea5b34 100644
--- a/target-i386/cpu-qom.h
+++ b/target-i386/cpu-qom.h
@@ -94,6 +94,7 @@ typedef struct X86CPU {
 bool hyperv_reset;
 bool hyperv_vpindex;
 bool hyperv_runtime;
+bool hyperv_synic;
 bool check_cpuid;
 bool enforce_cpuid;
 bool expose_kvm;
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index e5f1c5b..1462e19 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -3142,6 +3142,7 @@ static Property x86_cpu_properties[] = {
 DEFINE_PROP_BOOL("hv-reset", X86CPU, hyperv_reset, false),
 DEFINE_PROP_BOOL("hv-vpindex", X86CPU, hyperv_vpindex, false),
 DEFINE_PROP_BOOL("hv-runtime", X86CPU, hyperv_runtime, false),
+DEFINE_PROP_BOOL("hv-synic", X86CPU, hyperv_synic, false),
 DEFINE_PROP_BOOL("check", X86CPU, check_cpuid, true),
 DEFINE_PROP_BOOL("enforce", X86CPU, enforce_cpuid, false),
 DEFINE_PROP_BOOL("kvm", X86CPU, expose_kvm, true),
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index fc4a605..8cf33df 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -918,6 +918,11 @@ typedef struct CPUX86State {
 uint64_t msr_hv_tsc;
 uint64_t msr_hv_crash_params[HV_X64_MSR_CRASH_PARAMS];
 uint64_t msr_hv_runtime;
+uint64_t msr_hv_synic_control;
+uint64_t msr_hv_synic_version;
+uint64_t msr_hv_synic_evt_page;
+uint64_t msr_hv_synic_msg_page;
+uint64_t msr_hv_synic_sint[HV_SYNIC_SINT_COUNT];
 
 /* exception/interrupt handling */
 int error_code;
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 2a9953b..cfcd01d 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -86,6 +86,7 @@ static bool has_msr_hv_crash;
 static bool has_msr_hv_reset;
 static bool has_msr_hv_vpindex;
 static bool has_msr_hv_runtime;
+static bool has_msr_hv_synic;
 static bool has_msr_mtrr;
 static bool has_msr_xss;
 
@@ -521,7 +522,8 @@ static bool hyperv_enabled(X86CPU *cpu)
 cpu->hyperv_crash ||
 cpu->hyperv_reset ||
 cpu->hyperv_vpindex ||
-cpu->hyperv_runtime);
+cpu->hyperv_runtime ||
+cpu->hyperv_synic);
 }
 
 static Error *invtsc_mig_blocker;
@@ -610,6 +612,14 @@ int kvm_arch_init_vcpu(CPUState *cs)
 if (cpu->hyperv_runtime && has_msr_hv_runtime) {
 c->eax |= HV_X64_MSR_VP_RUNTIME_AVAILABLE;
 }
+if (cpu->hyperv_synic) {
+if (!has_msr_hv_synic ||
+kvm_vcpu_enable_cap(cs, KVM_CAP_HYPERV_SYNIC, 0)) {
+fprintf(stderr, "Hyper-V SynIC is not supported by kernel\n");
+return -ENOSYS;
+}
+c->eax |= HV_X64_MSR_SYNIC_AVAILABLE;
+}
 c = &cpuid_data.entries[cpuid_i++];
 c->function = HYPERV_CPUID_ENLIGHTMENT_INFO;
 if (cpu->hyperv_relaxed_timing) {
@@ -950,6 +960,10 @@ static int kvm_get_supported_msrs(KVMState *s)
 has_msr_hv_runtime = true;
 continue;
 }
+if (kvm_msr_list->indices[i] == HV_X64_MSR_SCONTROL) {
+has_msr_hv_synic = true;
+continue;
+}
 }
 }
 
@@ -1511,6 +1525,31 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
 kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_VP_RUNTIME,
   env->msr_hv_runtime);
 }
+if (cpu->hyperv_synic) {
+int j;
+
+if (!env->msr_hv_synic_version) {
+/* First time initialization */
+env->msr_hv_synic_version = HV_SYNIC_VERSION_1;
+for (j = 0; j < ARRAY_SIZE(env->msr_hv_synic_sint); j++) {
+env->msr_hv_synic_sint[j] = HV_SYNIC_SINT_MASK

[Qemu-devel] [PATCH v4 4/5] kvm/x86: Hyper-V synthetic interrupt controller

2015-11-10 Thread Andrey Smetanin
SynIC (synthetic interrupt controller) is a lapic extension,
which is controlled via MSRs and maintains for each vCPU
 - 16 synthetic interrupt "lines" (SINT's); each can be configured to
   trigger a specific interrupt vector optionally with auto-EOI
   semantics
 - a message page in the guest memory with 16 256-byte per-SINT message
   slots
 - an event flag page in the guest memory with 16 2048-bit per-SINT
   event flag areas

The host triggers a SINT whenever it delivers a new message to the
corresponding slot or flips an event flag bit in the corresponding area.
The guest informs the host that it can try delivering a message by
explicitly asserting EOI in lapic or writing to End-Of-Message (EOM)
MSR.

The userspace (qemu) triggers interrupts and receives EOM notifications
via irqfd with resampler; for that, a GSI is allocated for each
configured SINT, and irq_routing api is extended to support GSI-SINT
mapping.

Changes v4:
* added activation of SynIC by vcpu KVM_ENABLE_CAP
* added per SynIC active flag
* added deactivation of APICv upon SynIC activation

Changes v3:
* added KVM_CAP_HYPERV_SYNIC and KVM_IRQ_ROUTING_HV_SINT notes into
docs

Changes v2:
* do not use posted interrupts for Hyper-V SynIC AutoEOI vectors
* add Hyper-V SynIC vectors into EOI exit bitmap
* Hyper-V SyniIC SINT msr write logic simplified

Signed-off-by: Andrey Smetanin 
Reviewed-by: Roman Kagan 
Signed-off-by: Denis V. Lunev 
CC: Gleb Natapov 
CC: Paolo Bonzini 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: qemu-devel@nongnu.org

---
 Documentation/virtual/kvm/api.txt |  19 +++
 arch/x86/include/asm/kvm_host.h   |  15 ++
 arch/x86/kvm/hyperv.c | 315 ++
 arch/x86/kvm/hyperv.h |  23 +++
 arch/x86/kvm/irq_comm.c   |  34 
 arch/x86/kvm/lapic.c  |  15 +-
 arch/x86/kvm/lapic.h  |   5 +
 arch/x86/kvm/x86.c|  34 +++-
 include/linux/kvm_host.h  |   6 +
 include/uapi/linux/kvm.h  |   8 +
 10 files changed, 467 insertions(+), 7 deletions(-)

diff --git a/Documentation/virtual/kvm/api.txt 
b/Documentation/virtual/kvm/api.txt
index 34cc068..16096a2 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -1451,6 +1451,7 @@ struct kvm_irq_routing_entry {
struct kvm_irq_routing_irqchip irqchip;
struct kvm_irq_routing_msi msi;
struct kvm_irq_routing_s390_adapter adapter;
+   struct kvm_irq_routing_hv_sint hv_sint;
__u32 pad[8];
} u;
 };
@@ -1459,6 +1460,7 @@ struct kvm_irq_routing_entry {
 #define KVM_IRQ_ROUTING_IRQCHIP 1
 #define KVM_IRQ_ROUTING_MSI 2
 #define KVM_IRQ_ROUTING_S390_ADAPTER 3
+#define KVM_IRQ_ROUTING_HV_SINT 4
 
 No flags are specified so far, the corresponding field must be set to zero.
 
@@ -1482,6 +1484,10 @@ struct kvm_irq_routing_s390_adapter {
__u32 adapter_id;
 };
 
+struct kvm_irq_routing_hv_sint {
+   __u32 vcpu;
+   __u32 sint;
+};
 
 4.53 KVM_ASSIGN_SET_MSIX_NR (deprecated)
 
@@ -3685,3 +3691,16 @@ available, means that that the kernel has an 
implementation of the
 H_RANDOM hypercall backed by a hardware random-number generator.
 If present, the kernel H_RANDOM handler can be enabled for guest use
 with the KVM_CAP_PPC_ENABLE_HCALL capability.
+
+8.2 KVM_CAP_HYPERV_SYNIC
+
+Architectures: x86
+This capability, if KVM_CHECK_EXTENSION indicates that it is
+available, means that that the kernel has an implementation of the
+Hyper-V Synthetic interrupt controller(SynIC). Hyper-V SynIC is
+used to support Windows Hyper-V based guest paravirt drivers(VMBus).
+
+In order to use SynIC, it has to be activated by setting this
+capability via KVM_ENABLE_CAP ioctl on the vcpu fd. Note that this
+will disable the use of APIC hardware virtualization even if supported
+by the CPU, as it's incompatible with SynIC auto-EOI behavior.
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index a60a461..ad29e89 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -25,6 +25,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -374,10 +375,24 @@ struct kvm_mtrr {
struct list_head head;
 };
 
+/* Hyper-V synthetic interrupt controller (SynIC)*/
+struct kvm_vcpu_hv_synic {
+   u64 version;
+   u64 control;
+   u64 msg_page;
+   u64 evt_page;
+   atomic64_t sint[HV_SYNIC_SINT_COUNT];
+   atomic_t sint_to_gsi[HV_SYNIC_SINT_COUNT];
+   DECLARE_BITMAP(auto_eoi_bitmap, 256);
+   DECLARE_BITMAP(vec_bitmap, 256);
+   bool active;
+};
+
 /* Hyper-V per vcpu emulation context */
 struct kvm_vcpu_hv {
u64 hv_vapic;
s64 runtime_offset;
+   struct kvm_vcpu_hv_synic synic;
 };
 
 struct kvm_vcpu_arch {
diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index 62cf8c9..83a3c0c 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kv

Re: [Qemu-devel] [PATCH v1] kvm/x86: Hyper-V tsc page setup

2016-01-22 Thread Andrey Smetanin



On 01/22/2016 01:08 PM, Paolo Bonzini wrote:



On 24/12/2015 10:33, Andrey Smetanin wrote:

Lately tsc page was implemented but filled with empty
values. This patch setup tsc page scale and offset based
on vcpu tsc, tsc_khz and  HV_X64_MSR_TIME_REF_COUNT value.

The valid tsc page drops HV_X64_MSR_TIME_REF_COUNT msr
reads count to zero which potentially improves performance.

The patch applies on top of
'kvm: Make vcpu->requests as 64 bit bitmap'
previously sent.

Signed-off-by: Andrey Smetanin 
CC: Paolo Bonzini 
CC: Gleb Natapov 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: qemu-devel@nongnu.org


Actually there are some more issues:

- unless KVM can use a master clock, it is incorrect to set up the TSC
page this way; the sequence needs to be 0x in that case

0x is not an invalid value for tsc page,
see https://lkml.org/lkml/2015/11/2/655


- writing the TSC page must be done while all VCPUs are stopped, because
the TSC page doesn't provide the possibility for the guest to retry in
the middle of an update (like seqcount in Linux doess)
I think Windows guest gives tsc page address at boot time and protects 
against other vcpu's tsc page access.


In the end, the TSC page is actually pretty similar to the kvmclock
master clock and it makes sense to build it on the master clock too.
I'll post a patch next week.

Paolo


---
  arch/x86/kvm/hyperv.c| 117 +--
  arch/x86/kvm/hyperv.h|   2 +
  arch/x86/kvm/x86.c   |  12 +
  include/linux/kvm_host.h |   1 +
  4 files changed, 117 insertions(+), 15 deletions(-)

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index d50675a..504fdc7 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -753,6 +753,105 @@ static int kvm_hv_msr_set_crash_data(struct kvm_vcpu 
*vcpu,
return 0;
  }

+static u64 calc_tsc_page_scale(u32 tsc_khz)
+{
+   /*
+* reftime (in 100ns) = tsc * tsc_scale / 2^64 + tsc_offset
+* so reftime_delta = (tsc_delta * tsc_scale) / 2^64
+* so tsc_scale = (2^64 * reftime_delta)/tsc_delta
+* so tsc_scale = (2^64 * 10 * 10^6) / tsc_hz = (2^64 * 1) / tsc_khz
+* so tsc_scale = (2^63 * 2 * 1) / tsc_khz
+*/
+   return mul_u64_u32_div(1ULL << 63, 2 * 1, tsc_khz);
+}
+
+static int write_tsc_page(struct kvm *kvm, u64 gfn,
+ PHV_REFERENCE_TSC_PAGE tsc_ref)
+{
+   if (kvm_write_guest(kvm, gfn_to_gpa(gfn),
+   tsc_ref, sizeof(*tsc_ref)))
+   return 1;
+   mark_page_dirty(kvm, gfn);
+   return 0;
+}
+
+static int read_tsc_page(struct kvm *kvm, u64 gfn,
+PHV_REFERENCE_TSC_PAGE tsc_ref)
+{
+   if (kvm_read_guest(kvm, gfn_to_gpa(gfn),
+  tsc_ref, sizeof(*tsc_ref)))
+   return 1;
+   return 0;
+}
+
+static u64 calc_tsc_page_time(struct kvm_vcpu *vcpu,
+ PHV_REFERENCE_TSC_PAGE tsc_ref)
+{
+
+   u64 tsc = kvm_read_l1_tsc(vcpu, rdtsc());
+
+   return mul_u64_u64_shr(tsc, tsc_ref->tsc_scale, 64)
+   + tsc_ref->tsc_offset;
+}
+
+static int setup_blank_tsc_page(struct kvm_vcpu *vcpu, u64 gfn)
+{
+   HV_REFERENCE_TSC_PAGE tsc_ref;
+
+   memset(&tsc_ref, 0, sizeof(tsc_ref));
+   return write_tsc_page(vcpu->kvm, gfn, &tsc_ref);
+}
+
+int kvm_hv_setup_tsc_page(struct kvm_vcpu *vcpu)
+{
+   struct kvm *kvm = vcpu->kvm;
+   struct kvm_hv *hv = &kvm->arch.hyperv;
+   HV_REFERENCE_TSC_PAGE tsc_ref;
+   u32 tsc_khz;
+   int r;
+   u64 gfn, ref_time, tsc_scale, tsc_offset, tsc;
+
+   if (WARN_ON_ONCE(!(hv->hv_tsc_page & HV_X64_MSR_TSC_REFERENCE_ENABLE)))
+   return -EINVAL;
+
+   gfn = hv->hv_tsc_page >> HV_X64_MSR_TSC_REFERENCE_ADDRESS_SHIFT;
+   vcpu_debug(vcpu, "tsc page gfn 0x%llx\n", gfn);
+
+   tsc_khz = vcpu->arch.virtual_tsc_khz;
+   if (!tsc_khz) {
+   vcpu_unimpl(vcpu, "no tsc khz\n");
+   return setup_blank_tsc_page(vcpu, gfn);
+   }
+
+   r = read_tsc_page(kvm, gfn, &tsc_ref);
+   if (r) {
+   vcpu_err(vcpu, "can't access tsc page gfn 0x%llx\n", gfn);
+   return r;
+   }
+
+   tsc_scale = calc_tsc_page_scale(tsc_khz);
+   ref_time = get_time_ref_counter(kvm);
+   tsc = kvm_read_l1_tsc(vcpu, rdtsc());
+
+   /* tsc_offset = reftime - tsc * tsc_scale / 2^64 */
+   tsc_offset = ref_time - mul_u64_u64_shr(tsc, tsc_scale, 64);
+   vcpu_debug(vcpu, "tsc khz %u tsc %llu scale %llu offset %llu\n",
+  tsc_khz, tsc, tsc_scale, tsc_offset);
+
+   tsc_ref.tsc_sequence++;
+   if (tsc_ref.tsc_sequence == 0)
+   tsc_ref.tsc_sequence = 1;
+
+   tsc_ref.tsc_scale = tsc_scale;
+   tsc_ref.tsc_offset = tsc_offset;
+
+

Re: [Qemu-devel] [PATCH v1] kvm/x86: Hyper-V tsc page setup

2016-01-22 Thread Andrey Smetanin



On 01/22/2016 02:02 PM, Paolo Bonzini wrote:



On 22/01/2016 11:15, Andrey Smetanin wrote:


- unless KVM can use a master clock, it is incorrect to set up the TSC
page this way; the sequence needs to be 0x in that case

0x is not an invalid value for tsc page,
see https://lkml.org/lkml/2015/11/2/655


oh, I see now.


- writing the TSC page must be done while all VCPUs are stopped, because
the TSC page doesn't provide the possibility for the guest to retry in
the middle of an update (like seqcount in Linux doess)

I think Windows guest gives tsc page address at boot time and protects
against other vcpu's tsc page access.


Sometimes the TSC is detected to be unstable and Linux switches to
another clocksource.  At least in that case you can get a write to the
TSC page while the guest is running.


I can't understand how write is possible.
Linux Hyper-V driver hv_vmbus.ko does the following inside hv_init() 
drivers/hv/hv.c(line 256):


wrmsrl(HV_X64_MSR_REFERENCE_TSC, tsc_msr.as_uint64);
clocksource_register_hz(&hyperv_cs_tsc, NSEC_PER_SEC/100);

So page is setup only once before registration clock source.


In that case it would be enough to write a zero to tsc_sequence, which
_can_ be done atomically while the guest is running.  However, KVM
already has a mechanism to stop all VCPUs (KVM_REQ_MASTERCLOCK_UPDATE)
so we might as well use it.

Paolo





Re: [Qemu-devel] [PATCH v1] kvm/x86: Hyper-V tsc page setup

2016-01-22 Thread Andrey Smetanin



On 01/22/2016 02:02 PM, Paolo Bonzini wrote:



On 22/01/2016 11:15, Andrey Smetanin wrote:


- unless KVM can use a master clock, it is incorrect to set up the TSC
page this way; the sequence needs to be 0x in that case

0x is not an invalid value for tsc page,
see https://lkml.org/lkml/2015/11/2/655


oh, I see now.


- writing the TSC page must be done while all VCPUs are stopped, because
the TSC page doesn't provide the possibility for the guest to retry in
the middle of an update (like seqcount in Linux doess)

I think Windows guest gives tsc page address at boot time and protects
against other vcpu's tsc page access.


Sometimes the TSC is detected to be unstable and Linux switches to
another clocksource.  At least in that case you can get a write to the
TSC page while the guest is running.

Sorry, now I got it, you mean host TSC is unstable and we should mark
guest tsc page invalid. Now I understand please ignore my prev. message.


In that case it would be enough to write a zero to tsc_sequence, which
_can_ be done atomically while the guest is running.  However, KVM
already has a mechanism to stop all VCPUs (KVM_REQ_MASTERCLOCK_UPDATE)
so we might as well use it.

Paolo





Re: [Qemu-devel] [PATCH v1] kvm/x86: Hyper-V tsc page setup

2016-01-22 Thread Andrey Smetanin



On 01/22/2016 02:53 PM, Paolo Bonzini wrote:



On 22/01/2016 12:31, Andrey Smetanin wrote:


Sometimes the TSC is detected to be unstable and Linux switches to
another clocksource.  At least in that case you can get a write to the
TSC page while the guest is running.

Sorry, now I got it, you mean host TSC is unstable and we should mark
guest tsc page invalid. Now I understand please ignore my prev. message.


No problem.  Anyhow yes, this is what I meant: a host write to the TSC
page, not a guest write to the TSC page MSR.

Usually it happens only at migration time to update the sequence---which
I believe your patch wasn't doing either.

QEMU saves address of page inside ->msr_hv_tsc, so at restore
QEMU sets corresponding MSR and KVM setup's tsc page again.
So migration should able to work.
 But if we tie TSC page

updates to kvm_gen_update_masterclock, we get that for free when the
migration destination calls the KVM_SET_CLOCK ioctl.

Paolo





Re: [Qemu-devel] [PATCH v1] kvm/x86: Hyper-V tsc page setup

2016-01-22 Thread Andrey Smetanin



On 01/22/2016 01:08 PM, Paolo Bonzini wrote:



On 24/12/2015 10:33, Andrey Smetanin wrote:

Lately tsc page was implemented but filled with empty
values. This patch setup tsc page scale and offset based
on vcpu tsc, tsc_khz and  HV_X64_MSR_TIME_REF_COUNT value.

The valid tsc page drops HV_X64_MSR_TIME_REF_COUNT msr
reads count to zero which potentially improves performance.

The patch applies on top of
'kvm: Make vcpu->requests as 64 bit bitmap'
previously sent.

Signed-off-by: Andrey Smetanin 
CC: Paolo Bonzini 
CC: Gleb Natapov 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: qemu-devel@nongnu.org


Actually there are some more issues:

- unless KVM can use a master clock, it is incorrect to set up the TSC
page this way; the sequence needs to be 0x in that case

- writing the TSC page must be done while all VCPUs are stopped, because
the TSC page doesn't provide the possibility for the guest to retry in
the middle of an update (like seqcount in Linux doess)

In the end, the TSC page is actually pretty similar to the kvmclock
master clock and it makes sense to build it on the master clock too.
I'll post a patch next week.


We(@virtuozzo.com) will be very thankful to you for the patch which 
integrates Hyper-V tsc page with kvm clock. We even may do work by 
yourself, but our priority now is Hyper-V VMBus initialization
(which is not in dependency on Hyper-V tsc page). What is really helpful 
for us now - patches '[PATCH v2 0/5] KVM: Hyper-V VMBus hypercalls'.


Paolo


---
  arch/x86/kvm/hyperv.c| 117 +--
  arch/x86/kvm/hyperv.h|   2 +
  arch/x86/kvm/x86.c   |  12 +
  include/linux/kvm_host.h |   1 +
  4 files changed, 117 insertions(+), 15 deletions(-)

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index d50675a..504fdc7 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -753,6 +753,105 @@ static int kvm_hv_msr_set_crash_data(struct kvm_vcpu 
*vcpu,
return 0;
  }

+static u64 calc_tsc_page_scale(u32 tsc_khz)
+{
+   /*
+* reftime (in 100ns) = tsc * tsc_scale / 2^64 + tsc_offset
+* so reftime_delta = (tsc_delta * tsc_scale) / 2^64
+* so tsc_scale = (2^64 * reftime_delta)/tsc_delta
+* so tsc_scale = (2^64 * 10 * 10^6) / tsc_hz = (2^64 * 1) / tsc_khz
+* so tsc_scale = (2^63 * 2 * 1) / tsc_khz
+*/
+   return mul_u64_u32_div(1ULL << 63, 2 * 1, tsc_khz);
+}
+
+static int write_tsc_page(struct kvm *kvm, u64 gfn,
+ PHV_REFERENCE_TSC_PAGE tsc_ref)
+{
+   if (kvm_write_guest(kvm, gfn_to_gpa(gfn),
+   tsc_ref, sizeof(*tsc_ref)))
+   return 1;
+   mark_page_dirty(kvm, gfn);
+   return 0;
+}
+
+static int read_tsc_page(struct kvm *kvm, u64 gfn,
+PHV_REFERENCE_TSC_PAGE tsc_ref)
+{
+   if (kvm_read_guest(kvm, gfn_to_gpa(gfn),
+  tsc_ref, sizeof(*tsc_ref)))
+   return 1;
+   return 0;
+}
+
+static u64 calc_tsc_page_time(struct kvm_vcpu *vcpu,
+ PHV_REFERENCE_TSC_PAGE tsc_ref)
+{
+
+   u64 tsc = kvm_read_l1_tsc(vcpu, rdtsc());
+
+   return mul_u64_u64_shr(tsc, tsc_ref->tsc_scale, 64)
+   + tsc_ref->tsc_offset;
+}
+
+static int setup_blank_tsc_page(struct kvm_vcpu *vcpu, u64 gfn)
+{
+   HV_REFERENCE_TSC_PAGE tsc_ref;
+
+   memset(&tsc_ref, 0, sizeof(tsc_ref));
+   return write_tsc_page(vcpu->kvm, gfn, &tsc_ref);
+}
+
+int kvm_hv_setup_tsc_page(struct kvm_vcpu *vcpu)
+{
+   struct kvm *kvm = vcpu->kvm;
+   struct kvm_hv *hv = &kvm->arch.hyperv;
+   HV_REFERENCE_TSC_PAGE tsc_ref;
+   u32 tsc_khz;
+   int r;
+   u64 gfn, ref_time, tsc_scale, tsc_offset, tsc;
+
+   if (WARN_ON_ONCE(!(hv->hv_tsc_page & HV_X64_MSR_TSC_REFERENCE_ENABLE)))
+   return -EINVAL;
+
+   gfn = hv->hv_tsc_page >> HV_X64_MSR_TSC_REFERENCE_ADDRESS_SHIFT;
+   vcpu_debug(vcpu, "tsc page gfn 0x%llx\n", gfn);
+
+   tsc_khz = vcpu->arch.virtual_tsc_khz;
+   if (!tsc_khz) {
+   vcpu_unimpl(vcpu, "no tsc khz\n");
+   return setup_blank_tsc_page(vcpu, gfn);
+   }
+
+   r = read_tsc_page(kvm, gfn, &tsc_ref);
+   if (r) {
+   vcpu_err(vcpu, "can't access tsc page gfn 0x%llx\n", gfn);
+   return r;
+   }
+
+   tsc_scale = calc_tsc_page_scale(tsc_khz);
+   ref_time = get_time_ref_counter(kvm);
+   tsc = kvm_read_l1_tsc(vcpu, rdtsc());
+
+   /* tsc_offset = reftime - tsc * tsc_scale / 2^64 */
+   tsc_offset = ref_time - mul_u64_u64_shr(tsc, tsc_scale, 64);
+   vcpu_debug(vcpu, "tsc khz %u tsc %llu scale %llu offset %llu\n",
+  tsc_khz, tsc, tsc_scale, tsc_offset);
+
+   tsc_ref.tsc_sequence++;
+   if (ts

Re: [Qemu-devel] [PATCH v1] kvm/x86: Hyper-V tsc page setup

2016-01-22 Thread Andrey Smetanin



On 01/22/2016 04:21 PM, Paolo Bonzini wrote:



On 22/01/2016 14:13, Andrey Smetanin wrote:




We(@virtuozzo.com) will be very thankful to you for the patch which
integrates Hyper-V tsc page with kvm clock. We even may do work by
yourself, but our priority now is Hyper-V VMBus initialization
(which is not in dependency on Hyper-V tsc page). What is really helpful
for us now - patches '[PATCH v2 0/5] KVM: Hyper-V VMBus hypercalls'.


Yes, I want to merge that very soon as well.

Great, thanks!


Paolo





Re: [Qemu-devel] [PATCH v2 0/5] KVM: Hyper-V VMBus hypercalls

2016-02-02 Thread Andrey Smetanin

ping

On 01/21/2016 05:01 PM, Andrey Smetanin wrote:

The patch implements userspace exit 'KVM_EXIT_HYPERV'
for Hyper-V VMBus hypercalls(postmsg, signalevent)
to handle these hypercalls by QEMU.

Changes v2:
* use KVM_EXIT_HYPERV for hypercalls

Signed-off-by: Andrey Smetanin 
Reviewed-by: Roman Kagan 
CC: Gleb Natapov 
CC: Paolo Bonzini 
CC: Joerg Roedel 
CC: "K. Y. Srinivasan" 
CC: Haiyang Zhang 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: qemu-devel@nongnu.org

Andrey Smetanin (5):
   kvm/x86: Rename Hyper-V long spin wait hypercall
   drivers/hv: Move VMBus hypercall codes into Hyper-V UAPI header
   kvm/x86: Pass return code of kvm_emulate_hypercall
   kvm/x86: Reject Hyper-V hypercall continuation
   kvm/x86: Hyper-V VMBus hypercall userspace exit

  Documentation/virtual/kvm/api.txt  |  6 ++
  arch/x86/include/uapi/asm/hyperv.h |  4 +++-
  arch/x86/kvm/hyperv.c  | 40 +-
  arch/x86/kvm/hyperv.h  |  1 +
  arch/x86/kvm/svm.c |  3 +--
  arch/x86/kvm/vmx.c |  3 +--
  arch/x86/kvm/x86.c |  5 +
  drivers/hv/hv.c|  4 ++--
  drivers/hv/hyperv_vmbus.h  |  6 --
  include/uapi/linux/kvm.h   |  6 ++
  10 files changed, 56 insertions(+), 22 deletions(-)





Re: [Qemu-devel] [PATCH v2 2/5] target-i386/kvm: Hyper-V SynIC MSR's support

2015-11-11 Thread Andrey Smetanin



On 11/11/2015 12:17 PM, Paolo Bonzini wrote:



On 11/11/2015 10:09, Andrey Smetanin wrote:


I would prefer to put this in kvm_arch_init_vcpu, if possible.


Ok. I think the kvm_arch_init_vcpu() is called after migration restores
cpu->env->msr_hv_synic_* values, so unconditional initialization of
cpu->env->msr_hv_synic_* values can overwrite migrated values. The check
"if (!env->msr_hv_synic_version) {" is neccessary for first time
initialization to protect against such overwriting. This is why this
code migrates 'msr_hv_synic_version' value.


No, kvm_arch_init_vcpu is called at the very beginning, when the VCPU
thread is created.

main
-> machine_class->init
-> pc_init1
-> pc_cpus_init
-> pc_new_cpu
-> cpu_x86_create
-> object_property_set_bool
-> x86_cpu_realizefn
-> qemu_init_vcpu
-> qemu_kvm_start_vcpu
-> qemu_kvm_cpu_thread_fn (in new thread)
-> kvm_init_vcpu
-> kvm_arch_init_vcpu

This is long before qemu_start_incoming_migration, which is among the
last things done before calling main_loop
In this case I'll remove migration of msr_hv_synic_version and make 
first time initialization inside  kvm_arch_init_vcpu() - inside section 
where SynIC availability cpuid bit is set.


Thank you for clarification.


Paolo





Re: [Qemu-devel] [PATCH v2 2/5] target-i386/kvm: Hyper-V SynIC MSR's support

2015-11-11 Thread Andrey Smetanin



On 11/10/2015 04:14 PM, Paolo Bonzini wrote:



On 10/11/2015 13:52, Andrey Smetanin wrote:

This patch does Hyper-V Synthetic interrupt
controller(Hyper-V SynIC) MSR's support and
migration. Hyper-V SynIC is enabled by cpu's
'hv-synic' option.

This patch does not allow cpu creation if
'hv-synic' option specified but kernel
doesn't support Hyper-V SynIC.

Changes v2:
* activate Hyper-V SynIC by enabling corresponding vcpu cap
* reject cpu initialization if user requested Hyper-V SynIC
   but kernel does not support Hyper-V SynIC

Signed-off-by: Andrey Smetanin 
Reviewed-by: Roman Kagan 
Signed-off-by: Denis V. Lunev 
CC: Paolo Bonzini 
CC: Richard Henderson 
CC: Eduardo Habkost 
CC: "Andreas Färber" 
CC: Marcelo Tosatti 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: k...@vger.kernel.org

---
  target-i386/cpu-qom.h |  1 +
  target-i386/cpu.c |  1 +
  target-i386/cpu.h |  5 
  target-i386/kvm.c | 67 ++-
  target-i386/machine.c | 39 ++
  5 files changed, 112 insertions(+), 1 deletion(-)

diff --git a/target-i386/cpu-qom.h b/target-i386/cpu-qom.h
index e3bfe9d..7ea5b34 100644
--- a/target-i386/cpu-qom.h
+++ b/target-i386/cpu-qom.h
@@ -94,6 +94,7 @@ typedef struct X86CPU {
  bool hyperv_reset;
  bool hyperv_vpindex;
  bool hyperv_runtime;
+bool hyperv_synic;
  bool check_cpuid;
  bool enforce_cpuid;
  bool expose_kvm;
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index e5f1c5b..1462e19 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -3142,6 +3142,7 @@ static Property x86_cpu_properties[] = {
  DEFINE_PROP_BOOL("hv-reset", X86CPU, hyperv_reset, false),
  DEFINE_PROP_BOOL("hv-vpindex", X86CPU, hyperv_vpindex, false),
  DEFINE_PROP_BOOL("hv-runtime", X86CPU, hyperv_runtime, false),
+DEFINE_PROP_BOOL("hv-synic", X86CPU, hyperv_synic, false),
  DEFINE_PROP_BOOL("check", X86CPU, check_cpuid, true),
  DEFINE_PROP_BOOL("enforce", X86CPU, enforce_cpuid, false),
  DEFINE_PROP_BOOL("kvm", X86CPU, expose_kvm, true),
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index fc4a605..8cf33df 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -918,6 +918,11 @@ typedef struct CPUX86State {
  uint64_t msr_hv_tsc;
  uint64_t msr_hv_crash_params[HV_X64_MSR_CRASH_PARAMS];
  uint64_t msr_hv_runtime;
+uint64_t msr_hv_synic_control;
+uint64_t msr_hv_synic_version;
+uint64_t msr_hv_synic_evt_page;
+uint64_t msr_hv_synic_msg_page;
+uint64_t msr_hv_synic_sint[HV_SYNIC_SINT_COUNT];

  /* exception/interrupt handling */
  int error_code;
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 2a9953b..cfcd01d 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -86,6 +86,7 @@ static bool has_msr_hv_crash;
  static bool has_msr_hv_reset;
  static bool has_msr_hv_vpindex;
  static bool has_msr_hv_runtime;
+static bool has_msr_hv_synic;
  static bool has_msr_mtrr;
  static bool has_msr_xss;

@@ -521,7 +522,8 @@ static bool hyperv_enabled(X86CPU *cpu)
  cpu->hyperv_crash ||
  cpu->hyperv_reset ||
  cpu->hyperv_vpindex ||
-cpu->hyperv_runtime);
+cpu->hyperv_runtime ||
+cpu->hyperv_synic);
  }

  static Error *invtsc_mig_blocker;
@@ -610,6 +612,14 @@ int kvm_arch_init_vcpu(CPUState *cs)
  if (cpu->hyperv_runtime && has_msr_hv_runtime) {
  c->eax |= HV_X64_MSR_VP_RUNTIME_AVAILABLE;
  }
+if (cpu->hyperv_synic) {
+if (!has_msr_hv_synic ||
+kvm_vcpu_enable_cap(cs, KVM_CAP_HYPERV_SYNIC, 0)) {
+fprintf(stderr, "Hyper-V SynIC is not supported by kernel\n");
+return -ENOSYS;
+}
+c->eax |= HV_X64_MSR_SYNIC_AVAILABLE;
+}
  c = &cpuid_data.entries[cpuid_i++];
  c->function = HYPERV_CPUID_ENLIGHTMENT_INFO;
  if (cpu->hyperv_relaxed_timing) {
@@ -950,6 +960,10 @@ static int kvm_get_supported_msrs(KVMState *s)
  has_msr_hv_runtime = true;
  continue;
  }
+if (kvm_msr_list->indices[i] == HV_X64_MSR_SCONTROL) {
+has_msr_hv_synic = true;
+continue;
+}
  }
  }

@@ -1511,6 +1525,31 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
  kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_VP_RUNTIME,
env->msr_hv_runtime);
  }
+if (cpu->hyperv_synic) {
+int j;
+
+if (!env->msr_hv_synic_version) {
+/* First time initialization */
+env->msr_hv_synic_version = HV_SYNIC_VERSION_1;
+for

[Qemu-devel] [PATCH v3 2/5] target-i386/kvm: Hyper-V SynIC MSR's support

2015-11-11 Thread Andrey Smetanin
This patch does Hyper-V Synthetic interrupt
controller(Hyper-V SynIC) MSR's support and
migration. Hyper-V SynIC is enabled by cpu's
'hv-synic' option.

This patch does not allow cpu creation if
'hv-synic' option specified but kernel
doesn't support Hyper-V SynIC.

Changes v3:
* removed 'msr_hv_synic_version' migration because
it's value always the same
* moved SynIC msr's initialization into kvm_arch_init_vcpu

Signed-off-by: Andrey Smetanin 
Reviewed-by: Roman Kagan 
Signed-off-by: Denis V. Lunev 
CC: Paolo Bonzini 
CC: Richard Henderson 
CC: Eduardo Habkost 
CC: "Andreas Färber" 
CC: Marcelo Tosatti 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: k...@vger.kernel.org

---
 target-i386/cpu-qom.h |  1 +
 target-i386/cpu.c |  1 +
 target-i386/cpu.h |  5 
 target-i386/kvm.c | 66 ++-
 target-i386/machine.c | 37 +
 5 files changed, 109 insertions(+), 1 deletion(-)

diff --git a/target-i386/cpu-qom.h b/target-i386/cpu-qom.h
index e3bfe9d..7ea5b34 100644
--- a/target-i386/cpu-qom.h
+++ b/target-i386/cpu-qom.h
@@ -94,6 +94,7 @@ typedef struct X86CPU {
 bool hyperv_reset;
 bool hyperv_vpindex;
 bool hyperv_runtime;
+bool hyperv_synic;
 bool check_cpuid;
 bool enforce_cpuid;
 bool expose_kvm;
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index e5f1c5b..1462e19 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -3142,6 +3142,7 @@ static Property x86_cpu_properties[] = {
 DEFINE_PROP_BOOL("hv-reset", X86CPU, hyperv_reset, false),
 DEFINE_PROP_BOOL("hv-vpindex", X86CPU, hyperv_vpindex, false),
 DEFINE_PROP_BOOL("hv-runtime", X86CPU, hyperv_runtime, false),
+DEFINE_PROP_BOOL("hv-synic", X86CPU, hyperv_synic, false),
 DEFINE_PROP_BOOL("check", X86CPU, check_cpuid, true),
 DEFINE_PROP_BOOL("enforce", X86CPU, enforce_cpuid, false),
 DEFINE_PROP_BOOL("kvm", X86CPU, expose_kvm, true),
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index fc4a605..8cf33df 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -918,6 +918,11 @@ typedef struct CPUX86State {
 uint64_t msr_hv_tsc;
 uint64_t msr_hv_crash_params[HV_X64_MSR_CRASH_PARAMS];
 uint64_t msr_hv_runtime;
+uint64_t msr_hv_synic_control;
+uint64_t msr_hv_synic_version;
+uint64_t msr_hv_synic_evt_page;
+uint64_t msr_hv_synic_msg_page;
+uint64_t msr_hv_synic_sint[HV_SYNIC_SINT_COUNT];
 
 /* exception/interrupt handling */
 int error_code;
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 2a9953b..3f2ea90 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -86,6 +86,7 @@ static bool has_msr_hv_crash;
 static bool has_msr_hv_reset;
 static bool has_msr_hv_vpindex;
 static bool has_msr_hv_runtime;
+static bool has_msr_hv_synic;
 static bool has_msr_mtrr;
 static bool has_msr_xss;
 
@@ -521,7 +522,8 @@ static bool hyperv_enabled(X86CPU *cpu)
 cpu->hyperv_crash ||
 cpu->hyperv_reset ||
 cpu->hyperv_vpindex ||
-cpu->hyperv_runtime);
+cpu->hyperv_runtime ||
+cpu->hyperv_synic);
 }
 
 static Error *invtsc_mig_blocker;
@@ -610,6 +612,21 @@ int kvm_arch_init_vcpu(CPUState *cs)
 if (cpu->hyperv_runtime && has_msr_hv_runtime) {
 c->eax |= HV_X64_MSR_VP_RUNTIME_AVAILABLE;
 }
+if (cpu->hyperv_synic) {
+int sint;
+
+if (!has_msr_hv_synic ||
+kvm_vcpu_enable_cap(cs, KVM_CAP_HYPERV_SYNIC, 0)) {
+fprintf(stderr, "Hyper-V SynIC is not supported by kernel\n");
+return -ENOSYS;
+}
+
+c->eax |= HV_X64_MSR_SYNIC_AVAILABLE;
+env->msr_hv_synic_version = HV_SYNIC_VERSION_1;
+for (sint = 0; sint < ARRAY_SIZE(env->msr_hv_synic_sint); sint++) {
+env->msr_hv_synic_sint[sint] = HV_SYNIC_SINT_MASKED;
+}
+}
 c = &cpuid_data.entries[cpuid_i++];
 c->function = HYPERV_CPUID_ENLIGHTMENT_INFO;
 if (cpu->hyperv_relaxed_timing) {
@@ -950,6 +967,10 @@ static int kvm_get_supported_msrs(KVMState *s)
 has_msr_hv_runtime = true;
 continue;
 }
+if (kvm_msr_list->indices[i] == HV_X64_MSR_SCONTROL) {
+has_msr_hv_synic = true;
+continue;
+}
 }
 }
 
@@ -1511,6 +1532,23 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
 kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_VP_RUNTIME,
   env->msr_hv_runtime);
 }
+if (cpu->hyperv_synic) {
+int j;
+
+kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_SCONTROL

[Qemu-devel] [PATCH v1 4/7] kvm/x86: Added Hyper-V vcpu_to_hv_vcpu()/hv_vcpu_to_vcpu() helpers

2015-11-25 Thread Andrey Smetanin
Signed-off-by: Andrey Smetanin 
Reviewed-by: Roman Kagan 
CC: Gleb Natapov 
CC: Paolo Bonzini 
CC: "K. Y. Srinivasan" 
CC: Haiyang Zhang 
CC: Vitaly Kuznetsov 
CC: Roman Kagan 
CC: Denis V. Lunev 
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




[Qemu-devel] [PATCH v1 1/7] drivers/hv: Move HV_SYNIC_STIMER_COUNT into Hyper-V UAPI x86 header

2015-11-25 Thread Andrey Smetanin
This constant is required for Hyper-V SynIC timers MSR's
support by userspace(QEMU).

Signed-off-by: Andrey Smetanin 
Reviewed-by: Roman Kagan 
CC: Gleb Natapov 
CC: Paolo Bonzini 
CC: "K. Y. Srinivasan" 
CC: Haiyang Zhang 
CC: Vitaly Kuznetsov 
CC: Roman Kagan 
CC: Denis V. Lunev 
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 3782636..46e23d1 100644
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -102,8 +102,6 @@ enum hv_message_type {
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




[Qemu-devel] [PATCH v1 5/7] kvm/x86: Hyper-V internal helper to read MSR HV_X64_MSR_TIME_REF_COUNT

2015-11-25 Thread Andrey Smetanin
This helper will be used also in Hyper-V SynIC timers implementation.

Signed-off-by: Andrey Smetanin 
Reviewed-by: Roman Kagan 
CC: Gleb Natapov 
CC: Paolo Bonzini 
CC: "K. Y. Srinivasan" 
CC: Haiyang Zhang 
CC: Vitaly Kuznetsov 
CC: Roman Kagan 
CC: Denis V. Lunev 
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




[Qemu-devel] [PATCH v1 0/2] QEMU: Hyper-V SynIC timers MSR's support

2015-11-25 Thread Andrey Smetanin
Hyper-V SynIC timers are host timers that are configurable
by guest through corresponding MSR's (HV_X64_MSR_STIMER*).
Guest setup and use fired by host events(SynIC interrupt
and appropriate timer expiration message) as guest clock
events.

The state of Hyper-V SynIC timers are stored in corresponding
MSR's. This patch seria implements such MSR's support and migration.

Signed-off-by: Andrey Smetanin 
CC: Paolo Bonzini 
CC: Richard Henderson 
CC: Eduardo Habkost 
CC: "Andreas Färber" 
CC: Marcelo Tosatti 
CC: Denis V. Lunev 
CC: Roman Kagan 
CC: k...@vger.kernel.org

Andrey Smetanin (2):
  include: update Hyper-V header to include SynIC timers defines
  target-i386/kvm: Hyper-V SynIC timers MSR's support

 include/standard-headers/asm-x86/hyperv.h | 99 +++
 target-i386/cpu-qom.h |  1 +
 target-i386/cpu.c |  1 +
 target-i386/cpu.h |  2 +
 target-i386/kvm.c | 50 +++-
 target-i386/machine.c | 29 +
 6 files changed, 181 insertions(+), 1 deletion(-)

-- 
2.4.3




[Qemu-devel] [PATCH v1 2/7] drivers/hv: Move struct hv_message into UAPI Hyper-V x86 header

2015-11-25 Thread Andrey Smetanin
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 
Reviewed-by: Roman Kagan 
CC: Gleb Natapov 
CC: Paolo Bonzini 
CC: "K. Y. Srinivasan" 
CC: Haiyang Zhang 
CC: Vitaly Kuznetsov 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: qemu-devel@nongnu.org
---
 arch/x86/include/uapi/asm/hyperv.h | 91 ++
 drivers/hv/hyperv_vmbus.h  | 91 --
 2 files changed, 91 insertions(+), 91 deletions(-)

diff --git a/arch/x86/include/uapi/asm/hyperv.h 
b/arch/x86/include/uapi/asm/hyperv.h
index 07981f0..e86d77e 100644
--- a/arch/x86/include/uapi/asm/hyperv.h
+++ b/arch/x86/include/uapi/asm/hyperv.h
@@ -271,4 +271,95 @@ 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. */
+enum hv_message_type {
+   HVMSG_NONE  = 0x,
+
+   /* Memory access messages. */
+   HVMSG_UNMAPPED_GPA  = 0x8000,
+   HVMSG_GPA_INTERCEPT = 0x8001,
+
+   /* Timer notification messages. */
+   HVMSG_TIMER_EXPIRED = 0x8010,
+
+   /* Error messages. */
+   HVMSG_INVALID_VP_REGISTER_VALUE = 0x8020,
+   HVMSG_UNRECOVERABLE_EXCEPTION   = 0x8021,
+   HVMSG_UNSUPPORTED_FEATURE   = 0x8022,
+
+   /* Trace buffer complete messages. */
+   HVMSG_EVENTLOG_BUFFERCOMPLETE   = 0x8040,
+
+   /* Platform-specific processor intercept messages. */
+   HVMSG_X64_IOPORT_INTERCEPT  = 0x8001,
+   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
+};
+
+/* 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 port type. */
+enum hv_port_type {
+   HVPORT_MSG  = 1,
+   HVPORT_EVENT= 2,
+   HVPORT_MONITOR  = 3
+};
+
+/* Define synthetic interrupt controller message header. */
+struct hv_message_header {
+   enum hv_message_type message_type;
+   __u8 payload_size;
+   union hv_message_flags message_flags;
+   __u8 reserved[2];
+   union {
+   __u64 sender;
+   union hv_port_id port;
+   };
+};
+
+/* 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 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 46e23d1..d22230c 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  (0x)
 
 /* Define synthetic interrupt controller flag constants. */
@@ -74,53 +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. */
-enum hv_message_type {
-   HVMSG_NONE  = 0x,
-
-   /* Memory access messages. */
-   HVMSG_UNMAPPED_GPA  = 0x8000,
-   HVMSG_GPA_INTERCEPT = 0x8001,
-
-   /* Timer notification messages. */
-   HVMSG_TIMER_EXPIRED = 0x8010,
-
-   /* Error messages. */
-   HVMSG_INVALID_VP_REGISTER_VALUE = 

[Qemu-devel] [PATCH v1 7/7] kvm/x86: Hyper-V SynIC timers

2015-11-25 Thread Andrey Smetanin
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.

Signed-off-by: Andrey Smetanin 
CC: Gleb Natapov 
CC: Paolo Bonzini 
CC: "K. Y. Srinivasan" 
CC: Haiyang Zhang 
CC: Vitaly Kuznetsov 
CC: Roman Kagan 
CC: Denis V. Lunev 
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  | 325 -
 arch/x86/kvm/hyperv.h  |  24 +++
 arch/x86/kvm/x86.c |   9 +
 include/linux/kvm_host.h   |   1 +
 6 files changed, 375 insertions(+), 3 deletions(-)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index f608e17..e35c5ca 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -375,6 +375,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;
@@ -394,6 +405,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 e86d77e..f9d3349 100644
--- a/arch/x86/include/uapi/asm/hyperv.h
+++ b/arch/x86/include/uapi/asm/hyperv.h
@@ -362,4 +362,10 @@ struct hv_message_page {
struct hv_message sint_message[HV_SYNIC_SINT_COUNT];
 };
 
+#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..9f8eb82 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,275 @@ 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)
+  

[Qemu-devel] [PATCH v1 0/7] KVM: Hyper-V SynIC timers

2015-11-25 Thread Andrey Smetanin
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.

Signed-off-by: Andrey Smetanin 
CC: Gleb Natapov 
CC: Paolo Bonzini 
CC: "K. Y. Srinivasan" 
CC: Haiyang Zhang 
CC: Vitaly Kuznetsov 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: qemu-devel@nongnu.org

Andrey Smetanin (7):
  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
  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 |  99 ++
 arch/x86/kvm/hyperv.c  | 367 -
 arch/x86/kvm/hyperv.h  |  54 --
 arch/x86/kvm/x86.c |   9 +
 drivers/hv/hyperv_vmbus.h  |  93 --
 include/linux/kvm_host.h   |   3 +
 7 files changed, 527 insertions(+), 111 deletions(-)

-- 
2.4.3




[Qemu-devel] [PATCH v1 6/7] kvm/x86: Hyper-V SynIC message slot pending clearing at SINT ack

2015-11-25 Thread Andrey Smetanin
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 
CC: Gleb Natapov 
CC: Paolo Bonzini 
CC: "K. Y. Srinivasan" 
CC: Haiyang Zhang 
CC: Vitaly Kuznetsov 
CC: Roman Kagan 
CC: Denis V. Lunev 
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 
+#include 
 #include 
 #include 
 
@@ -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




[Qemu-devel] [PATCH v1 1/2] include: update Hyper-V header to include SynIC timers defines

2015-11-25 Thread Andrey Smetanin
This patch brings in the necessary changes from the corresponding kernel
patchset.  It's included only for completeness; ideally these changes
should arrive via the standard kernel header pull.

Signed-off-by: Andrey Smetanin 
CC: Paolo Bonzini 
CC: Richard Henderson 
CC: Eduardo Habkost 
CC: "Andreas Färber" 
CC: Marcelo Tosatti 
CC: Denis V. Lunev 
CC: Roman Kagan 
CC: k...@vger.kernel.org

---
 include/standard-headers/asm-x86/hyperv.h | 99 +++
 1 file changed, 99 insertions(+)

diff --git a/include/standard-headers/asm-x86/hyperv.h 
b/include/standard-headers/asm-x86/hyperv.h
index f9780f1..3684610 100644
--- a/include/standard-headers/asm-x86/hyperv.h
+++ b/include/standard-headers/asm-x86/hyperv.h
@@ -269,4 +269,103 @@ 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)
+
+/* 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. */
+enum hv_message_type {
+   HVMSG_NONE  = 0x,
+
+   /* Memory access messages. */
+   HVMSG_UNMAPPED_GPA  = 0x8000,
+   HVMSG_GPA_INTERCEPT = 0x8001,
+
+   /* Timer notification messages. */
+   HVMSG_TIMER_EXPIRED = 0x8010,
+
+   /* Error messages. */
+   HVMSG_INVALID_VP_REGISTER_VALUE = 0x8020,
+   HVMSG_UNRECOVERABLE_EXCEPTION   = 0x8021,
+   HVMSG_UNSUPPORTED_FEATURE   = 0x8022,
+
+   /* Trace buffer complete messages. */
+   HVMSG_EVENTLOG_BUFFERCOMPLETE   = 0x8040,
+
+   /* Platform-specific processor intercept messages. */
+   HVMSG_X64_IOPORT_INTERCEPT  = 0x8001,
+   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
+};
+
+/* Define synthetic interrupt controller message flags. */
+union hv_message_flags {
+   uint8_t asu8;
+   struct {
+   uint8_t msg_pending:1;
+   uint8_t reserved:7;
+   };
+};
+
+/* Define port identifier type. */
+union hv_port_id {
+   uint32_t asu32;
+   struct {
+   uint32_t id:24;
+   uint32_t reserved:8;
+   } u;
+};
+
+/* Define port type. */
+enum hv_port_type {
+   HVPORT_MSG  = 1,
+   HVPORT_EVENT= 2,
+   HVPORT_MONITOR  = 3
+};
+
+/* Define synthetic interrupt controller message header. */
+struct hv_message_header {
+   enum hv_message_type message_type;
+   uint8_t payload_size;
+   union hv_message_flags message_flags;
+   uint8_t reserved[2];
+   union {
+   uint64_t sender;
+   union hv_port_id port;
+   };
+};
+
+/* Define timer message payload structure. */
+struct hv_timer_message_payload {
+   uint32_t timer_index;
+   uint32_t reserved;
+   uint64_t expiration_time;   /* When the timer expired */
+   uint64_t delivery_time; /* When the message was delivered */
+};
+
+/* Define synthetic interrupt controller message format. */
+struct hv_message {
+   struct hv_message_header header;
+   union {
+   uint64_t 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];
+};
+
+#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) (uint8_t)(((config) >> 16) & 0x0F)
+
 #endif
-- 
2.4.3




[Qemu-devel] [PATCH v1 3/7] kvm/x86: Rearrange func's declarations inside Hyper-V header

2015-11-25 Thread Andrey Smetanin
This rearrangement places functions declarations together
according to their functionality, so future additions
will be simplier.

Signed-off-by: Andrey Smetanin 
Reviewed-by: Roman Kagan 
CC: Gleb Natapov 
CC: Paolo Bonzini 
CC: "K. Y. Srinivasan" 
CC: Haiyang Zhang 
CC: Vitaly Kuznetsov 
CC: Roman Kagan 
CC: Denis V. Lunev 
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




[Qemu-devel] [PATCH v1 2/2] target-i386/kvm: Hyper-V SynIC timers MSR's support

2015-11-25 Thread Andrey Smetanin
Hyper-V SynIC timers are host timers that are configurable
by guest through corresponding MSR's (HV_X64_MSR_STIMER*).
Guest setup and use fired by host events(SynIC interrupt
and appropriate timer expiration message) as guest clock
events.

The state of Hyper-V SynIC timers are stored in corresponding
MSR's. This patch seria implements such MSR's support and migration.

Signed-off-by: Andrey Smetanin 
CC: Paolo Bonzini 
CC: Richard Henderson 
CC: Eduardo Habkost 
CC: "Andreas Färber" 
CC: Marcelo Tosatti 
CC: Denis V. Lunev 
CC: Roman Kagan 
CC: k...@vger.kernel.org

---
 target-i386/cpu-qom.h |  1 +
 target-i386/cpu.c |  1 +
 target-i386/cpu.h |  2 ++
 target-i386/kvm.c | 50 +-
 target-i386/machine.c | 29 +
 5 files changed, 82 insertions(+), 1 deletion(-)

diff --git a/target-i386/cpu-qom.h b/target-i386/cpu-qom.h
index 7ea5b34..5f9d960 100644
--- a/target-i386/cpu-qom.h
+++ b/target-i386/cpu-qom.h
@@ -95,6 +95,7 @@ typedef struct X86CPU {
 bool hyperv_vpindex;
 bool hyperv_runtime;
 bool hyperv_synic;
+bool hyperv_stimer;
 bool check_cpuid;
 bool enforce_cpuid;
 bool expose_kvm;
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 1462e19..31407f1 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -3143,6 +3143,7 @@ static Property x86_cpu_properties[] = {
 DEFINE_PROP_BOOL("hv-vpindex", X86CPU, hyperv_vpindex, false),
 DEFINE_PROP_BOOL("hv-runtime", X86CPU, hyperv_runtime, false),
 DEFINE_PROP_BOOL("hv-synic", X86CPU, hyperv_synic, false),
+DEFINE_PROP_BOOL("hv-stimer", X86CPU, hyperv_stimer, false),
 DEFINE_PROP_BOOL("check", X86CPU, check_cpuid, true),
 DEFINE_PROP_BOOL("enforce", X86CPU, enforce_cpuid, false),
 DEFINE_PROP_BOOL("kvm", X86CPU, expose_kvm, true),
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 8cf33df..2376a55 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -923,6 +923,8 @@ typedef struct CPUX86State {
 uint64_t msr_hv_synic_evt_page;
 uint64_t msr_hv_synic_msg_page;
 uint64_t msr_hv_synic_sint[HV_SYNIC_SINT_COUNT];
+uint64_t msr_hv_stimer_config[HV_SYNIC_STIMER_COUNT];
+uint64_t msr_hv_stimer_count[HV_SYNIC_STIMER_COUNT];
 
 /* exception/interrupt handling */
 int error_code;
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 7513ef6..cb419ea 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -90,6 +90,7 @@ static bool has_msr_hv_reset;
 static bool has_msr_hv_vpindex;
 static bool has_msr_hv_runtime;
 static bool has_msr_hv_synic;
+static bool has_msr_hv_stimer;
 static bool has_msr_mtrr;
 static bool has_msr_xss;
 
@@ -526,7 +527,8 @@ static bool hyperv_enabled(X86CPU *cpu)
 cpu->hyperv_reset ||
 cpu->hyperv_vpindex ||
 cpu->hyperv_runtime ||
-cpu->hyperv_synic);
+cpu->hyperv_synic ||
+cpu->hyperv_stimer);
 }
 
 static Error *invtsc_mig_blocker;
@@ -630,6 +632,13 @@ int kvm_arch_init_vcpu(CPUState *cs)
 env->msr_hv_synic_sint[sint] = HV_SYNIC_SINT_MASKED;
 }
 }
+if (cpu->hyperv_stimer) {
+if (!has_msr_hv_stimer) {
+fprintf(stderr, "Hyper-V timers aren't supported by kernel\n");
+return -ENOSYS;
+}
+c->eax |= HV_X64_MSR_SYNTIMER_AVAILABLE;
+}
 c = &cpuid_data.entries[cpuid_i++];
 c->function = HYPERV_CPUID_ENLIGHTMENT_INFO;
 if (cpu->hyperv_relaxed_timing) {
@@ -974,6 +983,10 @@ static int kvm_get_supported_msrs(KVMState *s)
 has_msr_hv_synic = true;
 continue;
 }
+if (kvm_msr_list->indices[i] == HV_X64_MSR_STIMER0_CONFIG) {
+has_msr_hv_stimer = true;
+continue;
+}
 }
 }
 
@@ -1552,6 +1565,19 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
   env->msr_hv_synic_sint[j]);
 }
 }
+if (has_msr_hv_stimer) {
+int j;
+
+for (j = 0; j < ARRAY_SIZE(env->msr_hv_stimer_config); j++) {
+kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_STIMER0_CONFIG + j*2,
+env->msr_hv_stimer_config[j]);
+}
+
+for (j = 0; j < ARRAY_SIZE(env->msr_hv_stimer_count); j++) {
+kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_STIMER0_COUNT + j*2,
+env->msr_hv_stimer_count[j]);
+}
+}
 if (has_msr_mtrr) {
 kvm_msr_entry_set(&msrs[n++], MSR_MTRRdefType, env->mtrr_deftype);
 kvm_msr_entry_set(&msrs[n++],
@@ -1931,6 +1957,14 @@ s

Re: [Qemu-devel] [PATCH v1 6/7] kvm/x86: Hyper-V SynIC message slot pending clearing at SINT ack

2015-11-25 Thread Andrey Smetanin



On 11/25/2015 07:52 PM, Paolo Bonzini wrote:



On 25/11/2015 16:20, Andrey Smetanin wrote:

+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);


But the message page is not being pinned, is it?


Actually I don't know anything about pinning.
Is it pinning against page swapping ?
Could you please clarify and provide an API to use in this case ?

Paolo


+   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);
+}
+




[Qemu-devel] [PATCH v3 2/5] drivers/hv: Move VMBus hypercall codes into Hyper-V UAPI header

2016-02-11 Thread Andrey Smetanin
VMBus hypercall codes inside Hyper-V UAPI header will
be used by QEMU to implement VMBus host devices support.

Signed-off-by: Andrey Smetanin 
Acked-by: K. Y. Srinivasan 
Reviewed-by: Roman Kagan 
CC: Gleb Natapov 
CC: Paolo Bonzini 
CC: Joerg Roedel 
CC: "K. Y. Srinivasan" 
CC: Haiyang Zhang 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: qemu-devel@nongnu.org
---
 arch/x86/include/uapi/asm/hyperv.h | 2 ++
 drivers/hv/connection.c| 2 +-
 drivers/hv/hv.c| 2 +-
 drivers/hv/hyperv_vmbus.h  | 6 --
 4 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/arch/x86/include/uapi/asm/hyperv.h 
b/arch/x86/include/uapi/asm/hyperv.h
index 0c50fab..bc1c8a9 100644
--- a/arch/x86/include/uapi/asm/hyperv.h
+++ b/arch/x86/include/uapi/asm/hyperv.h
@@ -227,6 +227,8 @@
 
 /* Declare the various hypercall operations. */
 #define HV_X64_HCALL_NOTIFY_LONG_SPIN_WAIT 0x0008
+#define HV_X64_HCALL_POST_MESSAGE  0x005c
+#define HV_X64_HCALL_SIGNAL_EVENT  0x005d
 
 #define HV_X64_MSR_APIC_ASSIST_PAGE_ENABLE 0x0001
 #define HV_X64_MSR_APIC_ASSIST_PAGE_ADDRESS_SHIFT  12
diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
index fa86b2c..84700c6 100644
--- a/drivers/hv/connection.c
+++ b/drivers/hv/connection.c
@@ -485,5 +485,5 @@ void vmbus_set_event(struct vmbus_channel *channel)
(child_relid >> 5));
}
 
-   hv_do_hypercall(HVCALL_SIGNAL_EVENT, channel->sig_event, NULL);
+   hv_do_hypercall(HV_X64_HCALL_SIGNAL_EVENT, channel->sig_event, NULL);
 }
diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
index ccb335f..48388dc 100644
--- a/drivers/hv/hv.c
+++ b/drivers/hv/hv.c
@@ -337,7 +337,7 @@ int hv_post_message(union hv_connection_id connection_id,
aligned_msg->payload_size = payload_size;
memcpy((void *)aligned_msg->payload, payload, payload_size);
 
-   status = hv_do_hypercall(HVCALL_POST_MESSAGE, aligned_msg, NULL);
+   status = hv_do_hypercall(HV_X64_HCALL_POST_MESSAGE, aligned_msg, NULL);
 
put_cpu();
return status & 0x;
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
index b9ea7f5..1dabaa4 100644
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -256,12 +256,6 @@ struct hv_monitor_page {
u8 rsvdz4[1984];
 };
 
-/* Declare the various hypercall operations. */
-enum hv_call_code {
-   HVCALL_POST_MESSAGE = 0x005c,
-   HVCALL_SIGNAL_EVENT = 0x005d,
-};
-
 /* Definition of the hv_post_message hypercall input structure. */
 struct hv_input_post_message {
union hv_connection_id connectionid;
-- 
2.4.3




[Qemu-devel] [PATCH v3 1/5] kvm/x86: Rename Hyper-V long spin wait hypercall

2016-02-11 Thread Andrey Smetanin
Rename HV_X64_HV_NOTIFY_LONG_SPIN_WAIT
by HV_X64_HCALL_NOTIFY_LONG_SPIN_WAIT. So
the name better reflects hypercall codes accessory.

Signed-off-by: Andrey Smetanin 
Reviewed-by: Roman Kagan 
CC: Gleb Natapov 
CC: Paolo Bonzini 
CC: Joerg Roedel 
CC: "K. Y. Srinivasan" 
CC: Haiyang Zhang 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: qemu-devel@nongnu.org
---
 arch/x86/include/uapi/asm/hyperv.h | 2 +-
 arch/x86/kvm/hyperv.c  | 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 7956412..0c50fab 100644
--- a/arch/x86/include/uapi/asm/hyperv.h
+++ b/arch/x86/include/uapi/asm/hyperv.h
@@ -226,7 +226,7 @@
(~((1ull << HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_SHIFT) - 1))
 
 /* Declare the various hypercall operations. */
-#define HV_X64_HV_NOTIFY_LONG_SPIN_WAIT0x0008
+#define HV_X64_HCALL_NOTIFY_LONG_SPIN_WAIT 0x0008
 
 #define HV_X64_MSR_APIC_ASSIST_PAGE_ENABLE 0x0001
 #define HV_X64_MSR_APIC_ASSIST_PAGE_ADDRESS_SHIFT  12
diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index c58ba67..f1a42e1 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -1084,7 +1084,7 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
trace_kvm_hv_hypercall(code, fast, rep_cnt, rep_idx, ingpa, outgpa);
 
switch (code) {
-   case HV_X64_HV_NOTIFY_LONG_SPIN_WAIT:
+   case HV_X64_HCALL_NOTIFY_LONG_SPIN_WAIT:
kvm_vcpu_on_spin(vcpu);
break;
default:
-- 
2.4.3




[Qemu-devel] [PATCH v3 5/5] kvm/x86: Hyper-V VMBus hypercall userspace exit

2016-02-11 Thread Andrey Smetanin
The patch implements KVM_EXIT_HYPERV userspace exit
functionality for Hyper-V VMBus hypercalls:
HV_X64_HCALL_POST_MESSAGE, HV_X64_HCALL_SIGNAL_EVENT.

Changes v3:
* use vcpu->arch.complete_userspace_io to setup hypercall
result

Changes v2:
* use KVM_EXIT_HYPERV for hypercalls

Signed-off-by: Andrey Smetanin 
Reviewed-by: Roman Kagan 
CC: Gleb Natapov 
CC: Paolo Bonzini 
CC: Joerg Roedel 
CC: "K. Y. Srinivasan" 
CC: Haiyang Zhang 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: qemu-devel@nongnu.org
---
 Documentation/virtual/kvm/api.txt |  6 ++
 arch/x86/kvm/hyperv.c | 39 ---
 include/uapi/linux/kvm.h  |  6 ++
 3 files changed, 44 insertions(+), 7 deletions(-)

diff --git a/Documentation/virtual/kvm/api.txt 
b/Documentation/virtual/kvm/api.txt
index 07e4cdf..4a661e5 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -3339,6 +3339,7 @@ EOI was received.
 
struct kvm_hyperv_exit {
 #define KVM_EXIT_HYPERV_SYNIC  1
+#define KVM_EXIT_HYPERV_HCALL  2
__u32 type;
union {
struct {
@@ -3347,6 +3348,11 @@ EOI was received.
__u64 evt_page;
__u64 msg_page;
} synic;
+   struct {
+   __u64 input;
+   __u64 result;
+   __u64 params[2];
+   } hcall;
} u;
};
/* KVM_EXIT_HYPERV */
diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index e1daa8b..f8d97ee 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -1043,6 +1043,27 @@ bool kvm_hv_hypercall_enabled(struct kvm *kvm)
return kvm->arch.hyperv.hv_hypercall & HV_X64_MSR_HYPERCALL_ENABLE;
 }
 
+static void kvm_hv_hypercall_set_result(struct kvm_vcpu *vcpu, u64 result)
+{
+   bool longmode;
+
+   longmode = is_64_bit_mode(vcpu);
+   if (longmode)
+   kvm_register_write(vcpu, VCPU_REGS_RAX, result);
+   else {
+   kvm_register_write(vcpu, VCPU_REGS_RDX, result >> 32);
+   kvm_register_write(vcpu, VCPU_REGS_RAX, result & 0x);
+   }
+}
+
+static int kvm_hv_hypercall_complete_userspace(struct kvm_vcpu *vcpu)
+{
+   struct kvm_run *run = vcpu->run;
+
+   kvm_hv_hypercall_set_result(vcpu, run->hyperv.u.hcall.result);
+   return 1;
+}
+
 int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
 {
u64 param, ingpa, outgpa, ret;
@@ -1093,6 +1114,16 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
case HV_X64_HCALL_NOTIFY_LONG_SPIN_WAIT:
kvm_vcpu_on_spin(vcpu);
break;
+   case HV_X64_HCALL_POST_MESSAGE:
+   case HV_X64_HCALL_SIGNAL_EVENT:
+   vcpu->run->exit_reason = KVM_EXIT_HYPERV;
+   vcpu->run->hyperv.type = KVM_EXIT_HYPERV_HCALL;
+   vcpu->run->hyperv.u.hcall.input = param;
+   vcpu->run->hyperv.u.hcall.params[0] = ingpa;
+   vcpu->run->hyperv.u.hcall.params[1] = outgpa;
+   vcpu->arch.complete_userspace_io =
+   kvm_hv_hypercall_complete_userspace;
+   return 0;
default:
res = HV_STATUS_INVALID_HYPERCALL_CODE;
break;
@@ -1100,12 +1131,6 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
 
 set_result:
ret = res | (((u64)rep_done & 0xfff) << 32);
-   if (longmode) {
-   kvm_register_write(vcpu, VCPU_REGS_RAX, ret);
-   } else {
-   kvm_register_write(vcpu, VCPU_REGS_RDX, ret >> 32);
-   kvm_register_write(vcpu, VCPU_REGS_RAX, ret & 0x);
-   }
-
+   kvm_hv_hypercall_set_result(vcpu, ret);
return 1;
 }
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index a2fe0ac..82581b6 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -157,6 +157,7 @@ struct kvm_s390_skeys {
 
 struct kvm_hyperv_exit {
 #define KVM_EXIT_HYPERV_SYNIC  1
+#define KVM_EXIT_HYPERV_HCALL  2
__u32 type;
union {
struct {
@@ -165,6 +166,11 @@ struct kvm_hyperv_exit {
__u64 evt_page;
__u64 msg_page;
} synic;
+   struct {
+   __u64 input;
+   __u64 result;
+   __u64 params[2];
+   } hcall;
} u;
 };
 
-- 
2.4.3




[Qemu-devel] [PATCH v3 3/5] kvm/x86: Pass return code of kvm_emulate_hypercall

2016-02-11 Thread Andrey Smetanin
Pass the return code from kvm_emulate_hypercall on to the caller,
in order to allow it to indicate to the userspace that
the hypercall has to be handled there.

Also adjust all the existing code paths to return 1 to make sure the
hypercall isn't passed to the userspace without setting kvm_run
appropriately.

Signed-off-by: Andrey Smetanin 
Reviewed-by: Roman Kagan 
CC: Gleb Natapov 
CC: Paolo Bonzini 
CC: Joerg Roedel 
CC: "K. Y. Srinivasan" 
CC: Haiyang Zhang 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: qemu-devel@nongnu.org
---
 arch/x86/kvm/hyperv.c | 2 +-
 arch/x86/kvm/svm.c| 3 +--
 arch/x86/kvm/vmx.c| 3 +--
 3 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index f1a42e1..0e7c90f 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -1055,7 +1055,7 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
 */
if (kvm_x86_ops->get_cpl(vcpu) != 0 || !is_protmode(vcpu)) {
kvm_queue_exception(vcpu, UD_VECTOR);
-   return 0;
+   return 1;
}
 
longmode = is_64_bit_mode(vcpu);
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index c13a64b..9507038 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -1858,8 +1858,7 @@ static int halt_interception(struct vcpu_svm *svm)
 static int vmmcall_interception(struct vcpu_svm *svm)
 {
svm->next_rip = kvm_rip_read(&svm->vcpu) + 3;
-   kvm_emulate_hypercall(&svm->vcpu);
-   return 1;
+   return kvm_emulate_hypercall(&svm->vcpu);
 }
 
 static unsigned long nested_svm_get_tdp_cr3(struct kvm_vcpu *vcpu)
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 164eb9e..2edca5d 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -5747,8 +5747,7 @@ static int handle_halt(struct kvm_vcpu *vcpu)
 
 static int handle_vmcall(struct kvm_vcpu *vcpu)
 {
-   kvm_emulate_hypercall(vcpu);
-   return 1;
+   return kvm_emulate_hypercall(vcpu);
 }
 
 static int handle_invd(struct kvm_vcpu *vcpu)
-- 
2.4.3




[Qemu-devel] [PATCH v3 0/5] KVM: Hyper-V VMBus hypercalls

2016-02-11 Thread Andrey Smetanin
The patch implements userspace exit 'KVM_EXIT_HYPERV'
for Hyper-V VMBus hypercalls(postmsg, signalevent)
to handle these hypercalls by QEMU.

Changes v3:
* use vcpu->arch.complete_userspace_io to setup hypercall
result
* rebase for 'next-20160211'

Changes v2:
* use KVM_EXIT_HYPERV for hypercalls

Signed-off-by: Andrey Smetanin 
Reviewed-by: Roman Kagan 
CC: Gleb Natapov 
CC: Paolo Bonzini 
CC: Joerg Roedel 
CC: "K. Y. Srinivasan" 
CC: Haiyang Zhang 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: qemu-devel@nongnu.org

Andrey Smetanin (5):
  kvm/x86: Rename Hyper-V long spin wait hypercall
  drivers/hv: Move VMBus hypercall codes into Hyper-V UAPI header
  kvm/x86: Pass return code of kvm_emulate_hypercall
  kvm/x86: Reject Hyper-V hypercall continuation
  kvm/x86: Hyper-V VMBus hypercall userspace exit

 Documentation/virtual/kvm/api.txt  |  6 +
 arch/x86/include/uapi/asm/hyperv.h |  4 ++-
 arch/x86/kvm/hyperv.c  | 50 +++---
 arch/x86/kvm/svm.c |  3 +--
 arch/x86/kvm/vmx.c |  3 +--
 drivers/hv/connection.c|  2 +-
 drivers/hv/hv.c|  2 +-
 drivers/hv/hyperv_vmbus.h  |  6 -
 include/uapi/linux/kvm.h   |  6 +
 9 files changed, 60 insertions(+), 22 deletions(-)

-- 
2.4.3




[Qemu-devel] [PATCH v3 4/5] kvm/x86: Reject Hyper-V hypercall continuation

2016-02-11 Thread Andrey Smetanin
Currently we do not support Hyper-V hypercall continuation
so reject it.

Signed-off-by: Andrey Smetanin 
Reviewed-by: Roman Kagan 
CC: Gleb Natapov 
CC: Paolo Bonzini 
CC: Joerg Roedel 
CC: "K. Y. Srinivasan" 
CC: Haiyang Zhang 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: qemu-devel@nongnu.org
---
 arch/x86/kvm/hyperv.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index 0e7c90f..e1daa8b 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -1083,6 +1083,12 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
 
trace_kvm_hv_hypercall(code, fast, rep_cnt, rep_idx, ingpa, outgpa);
 
+   /* Hypercall continuation is not supported yet */
+   if (rep_cnt || rep_idx) {
+   res = HV_STATUS_INVALID_HYPERCALL_CODE;
+   goto set_result;
+   }
+
switch (code) {
case HV_X64_HCALL_NOTIFY_LONG_SPIN_WAIT:
kvm_vcpu_on_spin(vcpu);
@@ -1092,6 +1098,7 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
break;
}
 
+set_result:
ret = res | (((u64)rep_done & 0xfff) << 32);
if (longmode) {
kvm_register_write(vcpu, VCPU_REGS_RAX, ret);
-- 
2.4.3




Re: [Qemu-devel] [PATCH v3 2/5] drivers/hv: Move VMBus hypercall codes into Hyper-V UAPI header

2016-02-12 Thread Andrey Smetanin



On 02/12/2016 12:46 AM, Paolo Bonzini wrote:



On 11/02/2016 14:44, Andrey Smetanin wrote:

VMBus hypercall codes inside Hyper-V UAPI header will
be used by QEMU to implement VMBus host devices support.

Signed-off-by: Andrey Smetanin 
Acked-by: K. Y. Srinivasan 
Reviewed-by: Roman Kagan 
CC: Gleb Natapov 
CC: Paolo Bonzini 
CC: Joerg Roedel 
CC: "K. Y. Srinivasan" 
CC: Haiyang Zhang 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: qemu-devel@nongnu.org
---
  arch/x86/include/uapi/asm/hyperv.h | 2 ++
  drivers/hv/connection.c| 2 +-
  drivers/hv/hv.c| 2 +-
  drivers/hv/hyperv_vmbus.h  | 6 --
  4 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/arch/x86/include/uapi/asm/hyperv.h 
b/arch/x86/include/uapi/asm/hyperv.h
index 0c50fab..bc1c8a9 100644
--- a/arch/x86/include/uapi/asm/hyperv.h
+++ b/arch/x86/include/uapi/asm/hyperv.h
@@ -227,6 +227,8 @@

  /* Declare the various hypercall operations. */
  #define HV_X64_HCALL_NOTIFY_LONG_SPIN_WAIT0x0008
+#define HV_X64_HCALL_POST_MESSAGE  0x005c
+#define HV_X64_HCALL_SIGNAL_EVENT  0x005d

  #define HV_X64_MSR_APIC_ASSIST_PAGE_ENABLE0x0001
  #define HV_X64_MSR_APIC_ASSIST_PAGE_ADDRESS_SHIFT 12
diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
index fa86b2c..84700c6 100644
--- a/drivers/hv/connection.c
+++ b/drivers/hv/connection.c
@@ -485,5 +485,5 @@ void vmbus_set_event(struct vmbus_channel *channel)
(child_relid >> 5));
}

-   hv_do_hypercall(HVCALL_SIGNAL_EVENT, channel->sig_event, NULL);
+   hv_do_hypercall(HV_X64_HCALL_SIGNAL_EVENT, channel->sig_event, NULL);


What tree does this apply to?

next-20160211


Paolo


  }
diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
index ccb335f..48388dc 100644
--- a/drivers/hv/hv.c
+++ b/drivers/hv/hv.c
@@ -337,7 +337,7 @@ int hv_post_message(union hv_connection_id connection_id,
aligned_msg->payload_size = payload_size;
memcpy((void *)aligned_msg->payload, payload, payload_size);

-   status = hv_do_hypercall(HVCALL_POST_MESSAGE, aligned_msg, NULL);
+   status = hv_do_hypercall(HV_X64_HCALL_POST_MESSAGE, aligned_msg, NULL);

put_cpu();
return status & 0x;
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
index b9ea7f5..1dabaa4 100644
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -256,12 +256,6 @@ struct hv_monitor_page {
u8 rsvdz4[1984];
  };

-/* Declare the various hypercall operations. */
-enum hv_call_code {
-   HVCALL_POST_MESSAGE = 0x005c,
-   HVCALL_SIGNAL_EVENT = 0x005d,
-};
-
  /* Definition of the hv_post_message hypercall input structure. */
  struct hv_input_post_message {
union hv_connection_id connectionid;





Re: [Qemu-devel] [PATCH v1 0/7] KVM: Hyper-V SynIC timers

2015-11-26 Thread Andrey Smetanin



On 11/26/2015 08:28 AM, Wanpeng Li wrote:

2015-11-25 23:20 GMT+08:00 Andrey Smetanin :

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.


Could you post a link for this specification?


Official link:

http://download.microsoft.com/download/A/B/4/AB43A34E-BDD0-4FA6-BDEF-79EEF16E880B/Hypervisor%20Top%20Level%20Functional%20Specification%20v4.0.docx

and there is a pdf variant(my own docx -> pdf conversion):

https://www.dropbox.com/s/ehxictr5wgnedq7/Hypervisor%20Top%20Level%20Functional%20Specification%20v4.0.pdf?dl=0



Regards,
Wanpeng Li





Re: [Qemu-devel] [PATCH v1 6/7] kvm/x86: Hyper-V SynIC message slot pending clearing at SINT ack

2015-11-26 Thread Andrey Smetanin



On 11/25/2015 08:14 PM, Paolo Bonzini wrote:



On 25/11/2015 17:55, Andrey Smetanin wrote:


+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);


But the message page is not being pinned, is it?

Actually I don't know anything about pinning.
Is it pinning against page swapping ?


Yes.  Unless the page is pinned, kmap_atomic can fail.

kmap_atomic() can't fail for a valid page struct. Does
kvm_vcpu_gfn_to_page() can provide invalid page(swapped page) struct 
which may pass is_error_page(page) check but can leads to incorrect

behavior inside kmap_atomic()?


However, I don't think that kvm_hv_notify_acked_sint is called from
atomic context.  It is only called from apic_set_eoi.  Could you just
use kvm_vcpu_write_guest_page?
In this case I can use kvm_vcpu_write_guest_page(), but in the 'PATCH v1 
7/7' I do the same page mapping method to sync_cmpxchg() at guest 
message page address to exclusively acquire message page slot(see 
synic_deliver_msg()). So we need some method to map and access 
atomically memory of guest page in KVM. Does any method to pin and map 
guest page in kernel exists? Or should we use mlock() for this page in 
QEMU part ?


By the way, do you need to do this also in kvm_get_apic_interrupt, for
auto EOI interrupts?
No we don't need this because in case of auto EOI interrupts, if 
->msg_pending was set, host will receive HV_X64_MSR_EOM write request 
which calls kvm_hv_notify_acked_sint().


Thanks,

Paolo


Could you please clarify and provide an API to use in this case ?




Re: [Qemu-devel] [PATCH v1 6/7] kvm/x86: Hyper-V SynIC message slot pending clearing at SINT ack

2015-11-26 Thread Andrey Smetanin



On 11/26/2015 05:43 PM, Paolo Bonzini wrote:



On 26/11/2015 10:06, Andrey Smetanin wrote:



On 11/25/2015 08:14 PM, Paolo Bonzini wrote:



On 25/11/2015 17:55, Andrey Smetanin wrote:


+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);


But the message page is not being pinned, is it?

Actually I don't know anything about pinning.
Is it pinning against page swapping ?


Yes.  Unless the page is pinned, kmap_atomic can fail.

kmap_atomic() can't fail for a valid page struct. Does
kvm_vcpu_gfn_to_page() can provide invalid page(swapped page) struct
which may pass is_error_page(page) check but can leads to incorrect
behavior inside kmap_atomic()?


No, you're right.  Nevermind, I was confused because I thought you
needed kmap_atomic rather than kmap.  Here using kmap_atomic is just an
optimization, so it's okay.  (If you needed kmap_atomic, the problem
would have been that kvm_vcpu_gfn_to_page() can sleep).

In patch 7/7 you're also not in atomic context, so kvm_vcpu_gfn_to_page
is okay.

Shouldn't have reviewed the patch when tired. :)

Then the patches look good, I think.  With a testcase I can try them out
and hopefully merge them for Linux 4.5 / QEMU 2.6.

Thank you!

We already have a working Hyper-V SynIC timers kvm-unit-tests test case.
We are going to send appropriate patches seria into kvm-unit-tests git.

But  kvm-unit-tests master now broken:
> make
objcopy -O elf32-i386 x86/memory.elf x86/memory.flat
make: *** No rule to make target 'x86/pku.o', needed by 'x86/pku.elf'. 
Stop.


The problem is in latest commit 3da70799dd3cf1169c4668b4a3fd6f598528b8b9.

The commit adds 'pku' test case building, but not added any pku.c 
implementation file.


[root@asm-pc kvm-unit-tests]# ls -al x86/pku.c
ls: cannot access x86/pku.c: No such file or directory


Could you please fix it ?


Paolo





[Qemu-devel] [PATCH v1 1/5] lib/x86: Added Hyper-V MSR's availability bits into msr.h

2015-11-26 Thread Andrey Smetanin
Signed-off-by: Andrey Smetanin 
Reviewed-by: Roman Kagan 
CC: Paolo Bonzini 
CC: Marcelo Tosatti 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: qemu-devel@nongnu.org

---
 lib/x86/msr.h  | 4 
 x86/hyperv_synic.c | 2 +-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/lib/x86/msr.h b/lib/x86/msr.h
index 54da420..89ed718 100644
--- a/lib/x86/msr.h
+++ b/lib/x86/msr.h
@@ -408,6 +408,10 @@
 #define MSR_VM_IGNNE0xc0010115
 #define MSR_VM_HSAVE_PA 0xc0010117
 
+#define HV_X64_MSR_TIME_REF_COUNT_AVAILABLE (1 << 1)
+#define HV_X64_MSR_SYNIC_AVAILABLE  (1 << 2)
+#define HV_X64_MSR_SYNTIMER_AVAILABLE   (1 << 3)
+
 /* Define synthetic interrupt controller model specific registers. */
 #define HV_X64_MSR_SCONTROL 0x4080
 #define HV_X64_MSR_SVERSION 0x4081
diff --git a/x86/hyperv_synic.c b/x86/hyperv_synic.c
index 18d1295..eb141c1 100644
--- a/x86/hyperv_synic.c
+++ b/x86/hyperv_synic.c
@@ -11,7 +11,7 @@
 
 #define MAX_CPUS 4
 #define HYPERV_CPUID_FEATURES   0x4003
-#define HV_X64_MSR_SYNIC_AVAILABLE  (1 << 2)
+
 #define HV_SYNIC_CONTROL_ENABLE (1ULL << 0)
 #define HV_SYNIC_SIMP_ENABLE(1ULL << 0)
 #define HV_SYNIC_SIEFP_ENABLE   (1ULL << 0)
-- 
2.4.3




[Qemu-devel] [PATCH v1 3/5] lib/x86: Added Hyper-V SynIC timers MSR's values

2015-11-26 Thread Andrey Smetanin
Signed-off-by: Andrey Smetanin 
Reviewed-by: Roman Kagan 
CC: Paolo Bonzini 
CC: Marcelo Tosatti 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: qemu-devel@nongnu.org

---
 lib/x86/msr.h | 13 +
 1 file changed, 13 insertions(+)

diff --git a/lib/x86/msr.h b/lib/x86/msr.h
index 4ac9c71..d3f4198 100644
--- a/lib/x86/msr.h
+++ b/lib/x86/msr.h
@@ -437,4 +437,17 @@
 #define HV_X64_MSR_SINT14   0x409E
 #define HV_X64_MSR_SINT15   0x409F
 
+/*
+ * Synthetic Timer MSRs. Four timers per vcpu.
+ */
+
+#define HV_X64_MSR_STIMER0_CONFIG   0x40B0
+#define HV_X64_MSR_STIMER0_COUNT0x40B1
+#define HV_X64_MSR_STIMER1_CONFIG   0x40B2
+#define HV_X64_MSR_STIMER1_COUNT0x40B3
+#define HV_X64_MSR_STIMER2_CONFIG   0x40B4
+#define HV_X64_MSR_STIMER2_COUNT0x40B5
+#define HV_X64_MSR_STIMER3_CONFIG   0x40B6
+#define HV_X64_MSR_STIMER3_COUNT0x40B7
+
 #endif /* _ASM_X86_MSR_INDEX_H */
-- 
2.4.3




[Qemu-devel] [PATCH v1 0/5] KVM-UNIT-TESTS: Hyper-V SynIC timers test

2015-11-26 Thread Andrey Smetanin
The test checks Hyper-V SynIC timers functionality.
The test runs on every vCPU and performs start/stop
of periodic/one-shot timers (with period=1ms) and checks
validity of received expiration messages in appropriate
ISR's.

Signed-off-by: Andrey Smetanin 
Reviewed-by: Roman Kagan 
CC: Paolo Bonzini 
CC: Marcelo Tosatti 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: qemu-devel@nongnu.org

Andrey Smetanin (5):
  lib/x86: Added Hyper-V MSR's availability bits into msr.h
  lib/x86: Added HV_X64_MSR_TIME_REF_COUNT value into msr.h
  lib/x86: Added Hyper-V SynIC timers MSR's values
  lib/x86: Make free_page() available to call
  x86: Hyper-V SynIC timers test

 config/config-x86-common.mak |   4 +-
 lib/x86/msr.h|  19 ++
 lib/x86/vm.h |   1 +
 x86/hyperv_stimer.c  | 500 +++
 x86/hyperv_synic.c   |   2 +-
 x86/unittests.cfg|   5 +
 6 files changed, 529 insertions(+), 2 deletions(-)
 create mode 100644 x86/hyperv_stimer.c

-- 
2.4.3




[Qemu-devel] [PATCH v1 2/5] lib/x86: Added HV_X64_MSR_TIME_REF_COUNT value into msr.h

2015-11-26 Thread Andrey Smetanin
Signed-off-by: Andrey Smetanin 
Reviewed-by: Roman Kagan 
CC: Paolo Bonzini 
CC: Marcelo Tosatti 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: qemu-devel@nongnu.org

---
 lib/x86/msr.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lib/x86/msr.h b/lib/x86/msr.h
index 89ed718..4ac9c71 100644
--- a/lib/x86/msr.h
+++ b/lib/x86/msr.h
@@ -412,6 +412,8 @@
 #define HV_X64_MSR_SYNIC_AVAILABLE  (1 << 2)
 #define HV_X64_MSR_SYNTIMER_AVAILABLE   (1 << 3)
 
+#define HV_X64_MSR_TIME_REF_COUNT   0x4020
+
 /* Define synthetic interrupt controller model specific registers. */
 #define HV_X64_MSR_SCONTROL 0x4080
 #define HV_X64_MSR_SVERSION 0x4081
-- 
2.4.3




[Qemu-devel] [PATCH v1 5/5] x86: Hyper-V SynIC timers test

2015-11-26 Thread Andrey Smetanin
The test checks Hyper-V SynIC timers functionality.
The test runs on every vCPU and performs start/stop
of periodic/one-shot timers (with period=1ms) and checks
validity of received expiration messages in appropriate
ISR's.

Signed-off-by: Andrey Smetanin 
Reviewed-by: Roman Kagan 
CC: Paolo Bonzini 
CC: Marcelo Tosatti 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: qemu-devel@nongnu.org

---
 config/config-x86-common.mak |   4 +-
 x86/hyperv_stimer.c  | 500 +++
 x86/unittests.cfg|   5 +
 3 files changed, 508 insertions(+), 1 deletion(-)
 create mode 100644 x86/hyperv_stimer.c

diff --git a/config/config-x86-common.mak b/config/config-x86-common.mak
index f64874d..a75be87 100644
--- a/config/config-x86-common.mak
+++ b/config/config-x86-common.mak
@@ -37,7 +37,7 @@ tests-common = $(TEST_DIR)/vmexit.flat $(TEST_DIR)/tsc.flat \
$(TEST_DIR)/s3.flat $(TEST_DIR)/pmu.flat \
$(TEST_DIR)/tsc_adjust.flat $(TEST_DIR)/asyncpf.flat \
$(TEST_DIR)/init.flat $(TEST_DIR)/smap.flat \
-   $(TEST_DIR)/hyperv_synic.flat
+   $(TEST_DIR)/hyperv_synic.flat $(TEST_DIR)/hyperv_stimer.flat \
 
 ifdef API
 tests-common += api/api-sample
@@ -115,6 +115,8 @@ $(TEST_DIR)/memory.elf: $(cstart.o) $(TEST_DIR)/memory.o
 
 $(TEST_DIR)/hyperv_synic.elf: $(cstart.o) $(TEST_DIR)/hyperv_synic.o
 
+$(TEST_DIR)/hyperv_stimer.elf: $(cstart.o) $(TEST_DIR)/hyperv_stimer.o
+
 arch_clean:
$(RM) $(TEST_DIR)/*.o $(TEST_DIR)/*.flat $(TEST_DIR)/*.elf \
$(TEST_DIR)/.*.d lib/x86/.*.d
diff --git a/x86/hyperv_stimer.c b/x86/hyperv_stimer.c
new file mode 100644
index 000..e9186ca
--- /dev/null
+++ b/x86/hyperv_stimer.c
@@ -0,0 +1,500 @@
+#include "libcflat.h"
+#include "processor.h"
+#include "msr.h"
+#include "isr.h"
+#include "vm.h"
+#include "apic.h"
+#include "desc.h"
+#include "io.h"
+#include "smp.h"
+#include "atomic.h"
+
+#define MAX_CPUS 4
+#define HYPERV_CPUID_FEATURES   0x4003
+
+#define HV_SYNIC_CONTROL_ENABLE (1ULL << 0)
+#define HV_SYNIC_SIMP_ENABLE(1ULL << 0)
+#define HV_SYNIC_SIEFP_ENABLE   (1ULL << 0)
+#define HV_SYNIC_SINT_MASKED(1ULL << 16)
+#define HV_SYNIC_SINT_AUTO_EOI  (1ULL << 17)
+#define HV_SYNIC_SINT_VECTOR_MASK   (0xFF)
+#define HV_SYNIC_SINT_COUNT 16
+
+#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)
+
+#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. */
+enum hv_message_type {
+HVMSG_NONE  = 0x,
+
+/* Memory access messages. */
+HVMSG_UNMAPPED_GPA  = 0x8000,
+HVMSG_GPA_INTERCEPT = 0x8001,
+
+/* Timer notification messages. */
+HVMSG_TIMER_EXPIRED = 0x8010,
+
+/* Error messages. */
+HVMSG_INVALID_VP_REGISTER_VALUE = 0x8020,
+HVMSG_UNRECOVERABLE_EXCEPTION   = 0x8021,
+HVMSG_UNSUPPORTED_FEATURE   = 0x8022,
+
+/* Trace buffer complete messages. */
+HVMSG_EVENTLOG_BUFFERCOMPLETE   = 0x8040,
+
+/* Platform-specific processor intercept messages. */
+HVMSG_X64_IOPORT_INTERCEPT  = 0x8001,
+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
+};
+
+/* Define synthetic interrupt controller message flags. */
+union hv_message_flags {
+uint8_t asu8;
+struct {
+uint8_t msg_pending:1;
+uint8_t reserved:7;
+};
+};
+
+union hv_port_id {
+uint32_t asu32;
+struct {
+uint32_t id:24;
+uint32_t reserved:8;
+} u;
+};
+
+/* Define port type. */
+enum hv_port_type {
+HVPORT_MSG  = 1,
+HVPORT_EVENT= 2,
+HVPORT_MONITOR  = 3
+};
+
+/* Define synthetic interrupt controller message header. */
+struct hv_message_header {
+enum hv_message_type message_type;
+uint8_t payload_size;
+union hv_message_f

[Qemu-devel] [PATCH v1 4/5] lib/x86: Make free_page() available to call

2015-11-26 Thread Andrey Smetanin
This will be used to release allocated pages by Hyper-V
SynIC timers test.

Signed-off-by: Andrey Smetanin 
Reviewed-by: Roman Kagan 
CC: Paolo Bonzini 
CC: Marcelo Tosatti 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: qemu-devel@nongnu.org

---
 lib/x86/vm.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/lib/x86/vm.h b/lib/x86/vm.h
index bd73840..28794d7 100644
--- a/lib/x86/vm.h
+++ b/lib/x86/vm.h
@@ -33,6 +33,7 @@ unsigned long *install_pte(unsigned long *cr3,
unsigned long *pt_page);
 
 void *alloc_page();
+void free_page(void *page);
 
 unsigned long *install_large_page(unsigned long *cr3,unsigned long phys,
   void *virt);
-- 
2.4.3




Re: [Qemu-devel] [PATCH v1 2/7] drivers/hv: Move struct hv_message into UAPI Hyper-V x86 header

2015-11-27 Thread Andrey Smetanin



On 11/27/2015 12:34 PM, Paolo Bonzini wrote:



On 25/11/2015 16:20, Andrey Smetanin wrote:

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 
Reviewed-by: Roman Kagan 
CC: Gleb Natapov 
CC: Paolo Bonzini 
CC: "K. Y. Srinivasan" 
CC: Haiyang Zhang 
CC: Vitaly Kuznetsov 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: qemu-devel@nongnu.org
---
  arch/x86/include/uapi/asm/hyperv.h | 91 ++
  drivers/hv/hyperv_vmbus.h  | 91 --
  2 files changed, 91 insertions(+), 91 deletions(-)

diff --git a/arch/x86/include/uapi/asm/hyperv.h 
b/arch/x86/include/uapi/asm/hyperv.h
index 07981f0..e86d77e 100644
--- a/arch/x86/include/uapi/asm/hyperv.h
+++ b/arch/x86/include/uapi/asm/hyperv.h
@@ -271,4 +271,95 @@ 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. */
+enum hv_message_type {
+   HVMSG_NONE  = 0x,
+
+   /* Memory access messages. */
+   HVMSG_UNMAPPED_GPA  = 0x8000,
+   HVMSG_GPA_INTERCEPT = 0x8001,
+
+   /* Timer notification messages. */
+   HVMSG_TIMER_EXPIRED = 0x8010,
+
+   /* Error messages. */
+   HVMSG_INVALID_VP_REGISTER_VALUE = 0x8020,
+   HVMSG_UNRECOVERABLE_EXCEPTION   = 0x8021,
+   HVMSG_UNSUPPORTED_FEATURE   = 0x8022,
+
+   /* Trace buffer complete messages. */
+   HVMSG_EVENTLOG_BUFFERCOMPLETE   = 0x8040,
+
+   /* Platform-specific processor intercept messages. */
+   HVMSG_X64_IOPORT_INTERCEPT  = 0x8001,
+   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
+};
+
+/* 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 port type. */
+enum hv_port_type {
+   HVPORT_MSG  = 1,
+   HVPORT_EVENT= 2,
+   HVPORT_MONITOR  = 3
+};
+
+/* Define synthetic interrupt controller message header. */
+struct hv_message_header {
+   enum hv_message_type message_type;


Do not declare this as an enum, declare it as __u32 to make the size
portable.  It can be a patch on top.

Ok, I'll prepare such patch.


KY, can you ack these two patches?

Paolo


+   __u8 payload_size;
+   union hv_message_flags message_flags;
+   __u8 reserved[2];
+   union {
+   __u64 sender;
+   union hv_port_id port;
+   };
+};
+
+/* 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 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 46e23d1..d22230c 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 (0x)

  /* Define synthetic interrupt controller flag constants. */
@@ -74,53 +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. */
-enum hv_message_type {
-   HVMSG_NONE  = 0x,
-
-   /* Memory 

Re: [Qemu-devel] [PATCH v1 7/7] kvm/x86: Hyper-V SynIC timers

2015-11-27 Thread Andrey Smetanin



On 11/27/2015 01:49 PM, Paolo Bonzini wrote:



On 27/11/2015 09:12, Roman Kagan wrote:

+   n = div64_u64(time_now - stimer->exp_time, stimer->count) + 1;
+   stimer->exp_time += n * stimer->count;

This is actually just a reminder calculation so I'd rather do it
directly with div64_u64_rem().


It took me a while to understand why it was a remained. :)  Expanding
Andrey's formula you get

exp_time = exp_time + count + (time_now - exp_time) / count * count

the remainder, (time_now - exp_time) % count would be

time_now - exp_time - (time_now - exp_time) / count * count

so -((time_now - exp_time) % count) is

exp_time - time_now + (time_now - exp_time) / count * count

so Andrey's expression is

exp_time = time_now + (count - (time_now - exp_time) % count)

Yeah, that looks nice.

I'll redo this way.


Paolo





Re: [Qemu-devel] [PATCH v1 5/5] x86: Hyper-V SynIC timers test

2015-11-27 Thread Andrey Smetanin



On 11/27/2015 02:17 PM, Paolo Bonzini wrote:

The test logic is good, but the glue can be improved a bit so that the
output is more useful if it breaks.

Thanks for comments below. I'll redo this patch.


On 26/11/2015 17:29, Andrey Smetanin wrote:

The test checks Hyper-V SynIC timers functionality.
The test runs on every vCPU and performs start/stop
of periodic/one-shot timers (with period=1ms) and checks
validity of received expiration messages in appropriate
ISR's.

Signed-off-by: Andrey Smetanin 
Reviewed-by: Roman Kagan 
CC: Paolo Bonzini 
CC: Marcelo Tosatti 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: qemu-devel@nongnu.org

---
  config/config-x86-common.mak |   4 +-
  x86/hyperv_stimer.c  | 500 +++
  x86/unittests.cfg|   5 +
  3 files changed, 508 insertions(+), 1 deletion(-)
  create mode 100644 x86/hyperv_stimer.c

diff --git a/config/config-x86-common.mak b/config/config-x86-common.mak
index f64874d..a75be87 100644
--- a/config/config-x86-common.mak
+++ b/config/config-x86-common.mak
@@ -37,7 +37,7 @@ tests-common = $(TEST_DIR)/vmexit.flat $(TEST_DIR)/tsc.flat \
 $(TEST_DIR)/s3.flat $(TEST_DIR)/pmu.flat \
 $(TEST_DIR)/tsc_adjust.flat $(TEST_DIR)/asyncpf.flat \
 $(TEST_DIR)/init.flat $(TEST_DIR)/smap.flat \
-   $(TEST_DIR)/hyperv_synic.flat
+   $(TEST_DIR)/hyperv_synic.flat $(TEST_DIR)/hyperv_stimer.flat \

  ifdef API
  tests-common += api/api-sample
@@ -115,6 +115,8 @@ $(TEST_DIR)/memory.elf: $(cstart.o) $(TEST_DIR)/memory.o

  $(TEST_DIR)/hyperv_synic.elf: $(cstart.o) $(TEST_DIR)/hyperv_synic.o

+$(TEST_DIR)/hyperv_stimer.elf: $(cstart.o) $(TEST_DIR)/hyperv_stimer.o
+
  arch_clean:
$(RM) $(TEST_DIR)/*.o $(TEST_DIR)/*.flat $(TEST_DIR)/*.elf \
$(TEST_DIR)/.*.d lib/x86/.*.d
diff --git a/x86/hyperv_stimer.c b/x86/hyperv_stimer.c
new file mode 100644
index 000..e9186ca
--- /dev/null
+++ b/x86/hyperv_stimer.c
@@ -0,0 +1,500 @@
+#include "libcflat.h"
+#include "processor.h"
+#include "msr.h"
+#include "isr.h"
+#include "vm.h"
+#include "apic.h"
+#include "desc.h"
+#include "io.h"
+#include "smp.h"
+#include "atomic.h"
+
+#define MAX_CPUS 4
+#define HYPERV_CPUID_FEATURES   0x4003
+
+#define HV_SYNIC_CONTROL_ENABLE (1ULL << 0)
+#define HV_SYNIC_SIMP_ENABLE(1ULL << 0)
+#define HV_SYNIC_SIEFP_ENABLE   (1ULL << 0)
+#define HV_SYNIC_SINT_MASKED(1ULL << 16)
+#define HV_SYNIC_SINT_AUTO_EOI  (1ULL << 17)
+#define HV_SYNIC_SINT_VECTOR_MASK   (0xFF)
+#define HV_SYNIC_SINT_COUNT 16
+
+#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)
+
+#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. */
+enum hv_message_type {
+HVMSG_NONE  = 0x,
+
+/* Memory access messages. */
+HVMSG_UNMAPPED_GPA  = 0x8000,
+HVMSG_GPA_INTERCEPT = 0x8001,
+
+/* Timer notification messages. */
+HVMSG_TIMER_EXPIRED = 0x8010,
+
+/* Error messages. */
+HVMSG_INVALID_VP_REGISTER_VALUE = 0x8020,
+HVMSG_UNRECOVERABLE_EXCEPTION   = 0x8021,
+HVMSG_UNSUPPORTED_FEATURE   = 0x8022,
+
+/* Trace buffer complete messages. */
+HVMSG_EVENTLOG_BUFFERCOMPLETE   = 0x8040,
+
+/* Platform-specific processor intercept messages. */
+HVMSG_X64_IOPORT_INTERCEPT  = 0x8001,
+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
+};
+
+/* Define synthetic interrupt controller message flags. */
+union hv_message_flags {
+uint8_t asu8;
+struct {
+uint8_t msg_pending:1;
+uint8_t reserved:7;
+};
+};
+
+union hv_port_id {
+uint32_t asu32;
+struct {
+uint32_t id:24;
+uint32_t reserved:8;
+} u;
+};
+
+/* Define port type. */
+enum hv_port_type {
+HVPORT

Re: [Qemu-devel] [PATCH v1 0/5] KVM-UNIT-TESTS: Hyper-V SynIC timers test

2015-11-27 Thread Andrey Smetanin



On 11/27/2015 02:17 PM, Paolo Bonzini wrote:



On 26/11/2015 17:29, Andrey Smetanin wrote:

The test checks Hyper-V SynIC timers functionality.
The test runs on every vCPU and performs start/stop
of periodic/one-shot timers (with period=1ms) and checks
validity of received expiration messages in appropriate
ISR's.

Signed-off-by: Andrey Smetanin 
Reviewed-by: Roman Kagan 
CC: Paolo Bonzini 
CC: Marcelo Tosatti 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: qemu-devel@nongnu.org

Andrey Smetanin (5):
   lib/x86: Added Hyper-V MSR's availability bits into msr.h
   lib/x86: Added HV_X64_MSR_TIME_REF_COUNT value into msr.h
   lib/x86: Added Hyper-V SynIC timers MSR's values
   lib/x86: Make free_page() available to call
   x86: Hyper-V SynIC timers test


In addition to my comments on 5/5, can you make instead a hyperv.h file
with all that you need in the two testcases?

Yes, I'll do it. Thanks!


Paolo


  config/config-x86-common.mak |   4 +-
  lib/x86/msr.h|  19 ++
  lib/x86/vm.h |   1 +
  x86/hyperv_stimer.c  | 500 +++
  x86/hyperv_synic.c   |   2 +-
  x86/unittests.cfg|   5 +
  6 files changed, 529 insertions(+), 2 deletions(-)
  create mode 100644 x86/hyperv_stimer.c





[Qemu-devel] [PATCH v2 2/9] drivers/hv: Move HV_SYNIC_STIMER_COUNT into Hyper-V UAPI x86 header

2015-11-30 Thread Andrey Smetanin
This constant is required for Hyper-V SynIC timers MSR's
support by userspace(QEMU).

Signed-off-by: Andrey Smetanin 
Acked-by: K. Y. Srinivasan 
Reviewed-by: Roman Kagan 
CC: Gleb Natapov 
CC: Paolo Bonzini 
CC: "K. Y. Srinivasan" 
CC: Haiyang Zhang 
CC: Vitaly Kuznetsov 
CC: Roman Kagan 
CC: Denis V. Lunev 
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




[Qemu-devel] [PATCH v2 6/9] kvm/x86: Added Hyper-V vcpu_to_hv_vcpu()/hv_vcpu_to_vcpu() helpers

2015-11-30 Thread Andrey Smetanin
Signed-off-by: Andrey Smetanin 
Reviewed-by: Roman Kagan 
CC: Gleb Natapov 
CC: Paolo Bonzini 
CC: "K. Y. Srinivasan" 
CC: Haiyang Zhang 
CC: Vitaly Kuznetsov 
CC: Roman Kagan 
CC: Denis V. Lunev 
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




[Qemu-devel] [PATCH v2 3/9] drivers/hv: Move struct hv_message into UAPI Hyper-V x86 header

2015-11-30 Thread Andrey Smetanin
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 
Acked-by: K. Y. Srinivasan 
Reviewed-by: Roman Kagan 
CC: Gleb Natapov 
CC: Paolo Bonzini 
CC: "K. Y. Srinivasan" 
CC: Haiyang Zhang 
CC: Vitaly Kuznetsov 
CC: Roman Kagan 
CC: Denis V. Lunev 
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 0x
+
+/* Memory access messages. */
+#define HVMSG_UNMAPPED_GPA 0x8000
+#define HVMSG_GPA_INTERCEPT0x8001
+
+/* Timer notification messages. */
+#define HVMSG_TIMER_EXPIRED0x8010
+
+/* Error messages. */
+#define HVMSG_INVALID_VP_REGISTER_VALUE0x8020
+#define HVMSG_UNRECOVERABLE_EXCEPTION  0x8021
+#define HVMSG_UNSUPPORTED_FEATURE  0x8022
+
+/* Trace buffer complete messages. */
+#define HVMSG_EVENTLOG_BUFFERCOMPLETE  0x8040
+
+/* Platform-specific processor intercept messages. */
+#define HVMSG_X64_IOPORT_INTERCEPT 0x8001
+#define HVMSG_X64_MSR_INTERCEPT0x80010001
+#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  (0x)
 
 /* 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 0x
-
-/* Memory access messages. */
-#define HVMSG_UNMAPPED_GPA 0x8000
-#define HVMSG_GPA_INTERCEPT0x8001
-
-/* Timer notification messages. */
-#define HVMSG_TIMER_EXPIRED0x8010
-
-/* Error messages. */
-#define HVMSG_INVALID_VP_REGISTER_VALUE0x8020
-#define HVMSG_UNRECOVERABLE_EXCEPTION  0x8021
-#define HVMSG_UNSUPPORTED_FEATURE  0x8022
-
-/* Trace buffer complete messages. */
-#define HVMSG_EVENTLOG_BUFFERCOMPLETE  0x8040
-
-/* Platform-specific processor intercept messages. */
-#define HVMSG_X64_IOPORT_INTERCEPT 0x8001
-#define HVMSG_X64_MSR_INTERCEPT0x80010001
-#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

[Qemu-devel] [PATCH v2 1/9] drivers/hv: replace enum hv_message_type by u32

2015-11-30 Thread Andrey Smetanin
enum hv_message_type inside struct hv_message, hv_post_message
is not size portable. Replace enum by u32.

Signed-off-by: Andrey Smetanin 
CC: Gleb Natapov 
CC: Paolo Bonzini 
CC: "K. Y. Srinivasan" 
CC: Haiyang Zhang 
CC: Vitaly Kuznetsov 
CC: Roman Kagan 
CC: Denis V. Lunev 
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  = 0x,
+#define HVMSG_NONE 0x
 
-   /* Memory access messages. */
-   HVMSG_UNMAPPED_GPA  = 0x8000,
-   HVMSG_GPA_INTERCEPT = 0x8001,
+/* Memory access messages. */
+#define HVMSG_UNMAPPED_GPA 0x8000
+#define HVMSG_GPA_INTERCEPT0x8001
 
-   /* Timer notification messages. */
-   HVMSG_TIMER_EXPIRED = 0x8010,
+/* Timer notification messages. */
+#define HVMSG_TIMER_EXPIRED0x8010
 
-   /* Error messages. */
-   HVMSG_INVALID_VP_REGISTER_VALUE = 0x8020,
-   HVMSG_UNRECOVERABLE_EXCEPTION   = 0x8021,
-   HVMSG_UNSUPPORTED_FEATURE   = 0x8022,
+/* Error messages. */
+#define HVMSG_INVALID_VP_REGISTER_VALUE0x8020
+#define HVMSG_UNRECOVERABLE_EXCEPTION  0x8021
+#define HVMSG_UNSUPPORTED_FEATURE  0x8022
 
-   /* Trace buffer complete messages. */
-   HVMSG_EVENTLOG_BUFFERCOMPLETE   = 0x8040,
+/* Trace buffer complete messages. */
+#define HVMSG_EVENTLOG_BUFFERCOMPLETE  0x8040
 
-   /* Platform-specific processor intercept messages. */
-   HVMSG_X64_IOPORT_INTERCEPT  = 0x8001,
-   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 0x8001
+#define HVMSG_X64_MSR_INTERCEPT0x80010001
+#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




[Qemu-devel] [PATCH v2 0/9] KVM: Hyper-V SynIC timers

2015-11-30 Thread Andrey Smetanin
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 
CC: Gleb Natapov 
CC: Paolo Bonzini 
CC: "K. Y. Srinivasan" 
CC: Haiyang Zhang 
CC: Vitaly Kuznetsov 
CC: Roman Kagan 
CC: Denis V. Lunev 
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




[Qemu-devel] [PATCH v2 5/9] kvm/x86: Rearrange func's declarations inside Hyper-V header

2015-11-30 Thread Andrey Smetanin
This rearrangement places functions declarations together
according to their functionality, so future additions
will be simplier.

Signed-off-by: Andrey Smetanin 
Reviewed-by: Roman Kagan 
CC: Gleb Natapov 
CC: Paolo Bonzini 
CC: "K. Y. Srinivasan" 
CC: Haiyang Zhang 
CC: Vitaly Kuznetsov 
CC: Roman Kagan 
CC: Denis V. Lunev 
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




[Qemu-devel] [PATCH v2 4/9] drivers/hv: Move struct hv_timer_message_payload into UAPI Hyper-V x86 header

2015-11-30 Thread Andrey Smetanin
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 
CC: Gleb Natapov 
CC: Paolo Bonzini 
CC: "K. Y. Srinivasan" 
CC: Haiyang Zhang 
CC: Vitaly Kuznetsov 
CC: Roman Kagan 
CC: Denis V. Lunev 
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




[Qemu-devel] [PATCH v2 7/9] kvm/x86: Hyper-V internal helper to read MSR HV_X64_MSR_TIME_REF_COUNT

2015-11-30 Thread Andrey Smetanin
This helper will be used also in Hyper-V SynIC timers implementation.

Signed-off-by: Andrey Smetanin 
Reviewed-by: Roman Kagan 
CC: Gleb Natapov 
CC: Paolo Bonzini 
CC: "K. Y. Srinivasan" 
CC: Haiyang Zhang 
CC: Vitaly Kuznetsov 
CC: Roman Kagan 
CC: Denis V. Lunev 
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




[Qemu-devel] [PATCH v2 8/9] kvm/x86: Hyper-V SynIC message slot pending clearing at SINT ack

2015-11-30 Thread Andrey Smetanin
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 
Reviewed-by: Roman Kagan 
CC: Gleb Natapov 
CC: Paolo Bonzini 
CC: "K. Y. Srinivasan" 
CC: Haiyang Zhang 
CC: Vitaly Kuznetsov 
CC: Roman Kagan 
CC: Denis V. Lunev 
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 
+#include 
 #include 
 #include 
 
@@ -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




[Qemu-devel] [PATCH v2 9/9] kvm/x86: Hyper-V SynIC timers

2015-11-30 Thread Andrey Smetanin
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 
Reviewed-by: Roman Kagan 
CC: Gleb Natapov 
CC: Paolo Bonzini 
CC: "K. Y. Srinivasan" 
CC: Haiyang Zhang 
CC: Vitaly Kuznetsov 
CC: Roman Kagan 
CC: Denis V. Lunev 
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

[Qemu-devel] [PATCH v2 0/3] KVM-UNIT-TESTS: Hyper-V SynIC timers test

2015-12-08 Thread Andrey Smetanin
The test checks Hyper-V SynIC timers functionality.
The test runs on every vCPU and performs start/stop
of periodic/one-shot timers (with period=1ms) and checks
validity of received expiration messages in appropriate
ISR's.

Changes v2:
* Share generic Hyper-V tests code
* Hyper-V SynIC timers test fixes to improve
readability and output

Signed-off-by: Andrey Smetanin 
Reviewed-by: Roman Kagan 
CC: Paolo Bonzini 
CC: Marcelo Tosatti 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: qemu-devel@nongnu.org

Andrey Smetanin (3):
  lib/x86: Make free_page() available to call
  x86/hyperv: Move Hyper-V generic code into hyperv.h/hyperv.c
  x86: Hyper-V SynIC timers test

 config/config-x86-common.mak |   8 +-
 lib/x86/msr.h|  23 ---
 lib/x86/vm.h |   1 +
 x86/hyperv.c |  24 +++
 x86/hyperv.h | 183 +
 x86/hyperv_stimer.c  | 376 +++
 x86/hyperv_synic.c   |  42 +
 x86/unittests.cfg|   5 +
 8 files changed, 603 insertions(+), 59 deletions(-)
 create mode 100644 x86/hyperv.c
 create mode 100644 x86/hyperv.h
 create mode 100644 x86/hyperv_stimer.c

-- 
2.4.3




[Qemu-devel] [PATCH v2 1/3] lib/x86: Make free_page() available to call

2015-12-08 Thread Andrey Smetanin
This will be used to release allocated pages by Hyper-V
SynIC timers test.

Signed-off-by: Andrey Smetanin 
Reviewed-by: Roman Kagan 
CC: Paolo Bonzini 
CC: Marcelo Tosatti 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: qemu-devel@nongnu.org
---
 lib/x86/vm.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/lib/x86/vm.h b/lib/x86/vm.h
index bd73840..28794d7 100644
--- a/lib/x86/vm.h
+++ b/lib/x86/vm.h
@@ -33,6 +33,7 @@ unsigned long *install_pte(unsigned long *cr3,
unsigned long *pt_page);
 
 void *alloc_page();
+void free_page(void *page);
 
 unsigned long *install_large_page(unsigned long *cr3,unsigned long phys,
   void *virt);
-- 
2.4.3




[Qemu-devel] [PATCH v2 2/3] x86/hyperv: Move Hyper-V generic code into hyperv.h/hyperv.c

2015-12-08 Thread Andrey Smetanin
This code will be used as shared between hyperv_synic
and hyperv_stimer tests.

Signed-off-by: Andrey Smetanin 
CC: Paolo Bonzini 
CC: Marcelo Tosatti 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: qemu-devel@nongnu.org
---
 config/config-x86-common.mak |  3 ++-
 lib/x86/msr.h| 23 --
 x86/hyperv.c | 24 ++
 x86/hyperv.h | 58 
 x86/hyperv_synic.c   | 42 ++--
 5 files changed, 92 insertions(+), 58 deletions(-)
 create mode 100644 x86/hyperv.c
 create mode 100644 x86/hyperv.h

diff --git a/config/config-x86-common.mak b/config/config-x86-common.mak
index f64874d..156be1c 100644
--- a/config/config-x86-common.mak
+++ b/config/config-x86-common.mak
@@ -113,7 +113,8 @@ $(TEST_DIR)/debug.elf: $(cstart.o) $(TEST_DIR)/debug.o
 
 $(TEST_DIR)/memory.elf: $(cstart.o) $(TEST_DIR)/memory.o
 
-$(TEST_DIR)/hyperv_synic.elf: $(cstart.o) $(TEST_DIR)/hyperv_synic.o
+$(TEST_DIR)/hyperv_synic.elf: $(cstart.o) $(TEST_DIR)/hyperv.o \
+  $(TEST_DIR)/hyperv_synic.o
 
 arch_clean:
$(RM) $(TEST_DIR)/*.o $(TEST_DIR)/*.flat $(TEST_DIR)/*.elf \
diff --git a/lib/x86/msr.h b/lib/x86/msr.h
index 54da420..281255a 100644
--- a/lib/x86/msr.h
+++ b/lib/x86/msr.h
@@ -408,27 +408,4 @@
 #define MSR_VM_IGNNE0xc0010115
 #define MSR_VM_HSAVE_PA 0xc0010117
 
-/* Define synthetic interrupt controller model specific registers. */
-#define HV_X64_MSR_SCONTROL 0x4080
-#define HV_X64_MSR_SVERSION 0x4081
-#define HV_X64_MSR_SIEFP0x4082
-#define HV_X64_MSR_SIMP 0x4083
-#define HV_X64_MSR_EOM  0x4084
-#define HV_X64_MSR_SINT00x4090
-#define HV_X64_MSR_SINT10x4091
-#define HV_X64_MSR_SINT20x4092
-#define HV_X64_MSR_SINT30x4093
-#define HV_X64_MSR_SINT40x4094
-#define HV_X64_MSR_SINT50x4095
-#define HV_X64_MSR_SINT60x4096
-#define HV_X64_MSR_SINT70x4097
-#define HV_X64_MSR_SINT80x4098
-#define HV_X64_MSR_SINT90x4099
-#define HV_X64_MSR_SINT10   0x409A
-#define HV_X64_MSR_SINT11   0x409B
-#define HV_X64_MSR_SINT12   0x409C
-#define HV_X64_MSR_SINT13   0x409D
-#define HV_X64_MSR_SINT14   0x409E
-#define HV_X64_MSR_SINT15   0x409F
-
 #endif /* _ASM_X86_MSR_INDEX_H */
diff --git a/x86/hyperv.c b/x86/hyperv.c
new file mode 100644
index 000..824773d
--- /dev/null
+++ b/x86/hyperv.c
@@ -0,0 +1,24 @@
+#include "hyperv.h"
+
+static void synic_ctl(u8 ctl, u8 vcpu_id, u8 sint)
+{
+outl((ctl << 16)|((vcpu_id) << 8)|sint, 0x3000);
+}
+
+void synic_sint_create(int vcpu, int sint, int vec, bool auto_eoi)
+{
+wrmsr(HV_X64_MSR_SINT0 + sint,
+  (u64)vec | ((auto_eoi) ? HV_SYNIC_SINT_AUTO_EOI : 0));
+synic_ctl(HV_TEST_DEV_SINT_ROUTE_CREATE, vcpu, sint);
+}
+
+void synic_sint_set(int vcpu, int sint)
+{
+synic_ctl(HV_TEST_DEV_SINT_ROUTE_SET_SINT, vcpu, sint);
+}
+
+void synic_sint_destroy(int vcpu, int sint)
+{
+wrmsr(HV_X64_MSR_SINT0 + sint, 0xFF|HV_SYNIC_SINT_MASKED);
+synic_ctl(HV_TEST_DEV_SINT_ROUTE_DESTROY, vcpu, sint);
+}
diff --git a/x86/hyperv.h b/x86/hyperv.h
new file mode 100644
index 000..0dd1d0d
--- /dev/null
+++ b/x86/hyperv.h
@@ -0,0 +1,58 @@
+#ifndef __HYPERV_H
+#define __HYPERV_H
+
+#include "libcflat.h"
+#include "processor.h"
+#include "io.h"
+
+#define HYPERV_CPUID_FEATURES   0x4003
+
+#define HV_X64_MSR_SYNIC_AVAILABLE  (1 << 2)
+
+/* Define synthetic interrupt controller model specific registers. */
+#define HV_X64_MSR_SCONTROL 0x4080
+#define HV_X64_MSR_SVERSION 0x4081
+#define HV_X64_MSR_SIEFP0x4082
+#define HV_X64_MSR_SIMP 0x4083
+#define HV_X64_MSR_EOM  0x4084
+#define HV_X64_MSR_SINT00x4090
+#define HV_X64_MSR_SINT10x4091
+#define HV_X64_MSR_SINT20x4092
+#define HV_X64_MSR_SINT30x4093
+#define HV_X64_MSR_SINT40x4094
+#define HV_X64_MSR_SINT50x4095
+#define HV_X64_MSR_SINT60x4096
+#define HV_X64_MSR_SINT70x4097
+#define HV_X64_MSR_SINT80x4098
+#define HV_X64_MSR_SINT9   

[Qemu-devel] [PATCH v2 3/3] x86: Hyper-V SynIC timers test

2015-12-08 Thread Andrey Smetanin
The test checks Hyper-V SynIC timers functionality.
The test runs on every vCPU and performs start/stop
of periodic/one-shot timers (with period=1ms) and checks
validity of received expiration messages in appropriate
ISR's.

Changes v2:
* reorg code to use generic hyperv.h
* split timer test into test cases with separate callbacks
* removed unnecessary irq_enable() calls
* moved sint's create/destoy into test prepare/cleanup callbacks
* defined used sint's numbers and vectors

Signed-off-by: Andrey Smetanin 
Reviewed-by: Roman Kagan 
CC: Paolo Bonzini 
CC: Marcelo Tosatti 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: qemu-devel@nongnu.org
---
 config/config-x86-common.mak |   5 +-
 x86/hyperv.h | 125 ++
 x86/hyperv_stimer.c  | 376 +++
 x86/unittests.cfg|   5 +
 4 files changed, 510 insertions(+), 1 deletion(-)
 create mode 100644 x86/hyperv_stimer.c

diff --git a/config/config-x86-common.mak b/config/config-x86-common.mak
index 156be1c..72b95e3 100644
--- a/config/config-x86-common.mak
+++ b/config/config-x86-common.mak
@@ -37,7 +37,7 @@ tests-common = $(TEST_DIR)/vmexit.flat $(TEST_DIR)/tsc.flat \
$(TEST_DIR)/s3.flat $(TEST_DIR)/pmu.flat \
$(TEST_DIR)/tsc_adjust.flat $(TEST_DIR)/asyncpf.flat \
$(TEST_DIR)/init.flat $(TEST_DIR)/smap.flat \
-   $(TEST_DIR)/hyperv_synic.flat
+   $(TEST_DIR)/hyperv_synic.flat $(TEST_DIR)/hyperv_stimer.flat \
 
 ifdef API
 tests-common += api/api-sample
@@ -116,6 +116,9 @@ $(TEST_DIR)/memory.elf: $(cstart.o) $(TEST_DIR)/memory.o
 $(TEST_DIR)/hyperv_synic.elf: $(cstart.o) $(TEST_DIR)/hyperv.o \
   $(TEST_DIR)/hyperv_synic.o
 
+$(TEST_DIR)/hyperv_stimer.elf: $(cstart.o) $(TEST_DIR)/hyperv.o \
+   $(TEST_DIR)/hyperv_stimer.o
+
 arch_clean:
$(RM) $(TEST_DIR)/*.o $(TEST_DIR)/*.flat $(TEST_DIR)/*.elf \
$(TEST_DIR)/.*.d lib/x86/.*.d
diff --git a/x86/hyperv.h b/x86/hyperv.h
index 0dd1d0d..faf931b 100644
--- a/x86/hyperv.h
+++ b/x86/hyperv.h
@@ -7,7 +7,11 @@
 
 #define HYPERV_CPUID_FEATURES   0x4003
 
+#define HV_X64_MSR_TIME_REF_COUNT_AVAILABLE (1 << 1)
 #define HV_X64_MSR_SYNIC_AVAILABLE  (1 << 2)
+#define HV_X64_MSR_SYNTIMER_AVAILABLE   (1 << 3)
+
+#define HV_X64_MSR_TIME_REF_COUNT   0x4020
 
 /* Define synthetic interrupt controller model specific registers. */
 #define HV_X64_MSR_SCONTROL 0x4080
@@ -32,6 +36,19 @@
 #define HV_X64_MSR_SINT14   0x409E
 #define HV_X64_MSR_SINT15   0x409F
 
+/*
+ * Synthetic Timer MSRs. Four timers per vcpu.
+ */
+
+#define HV_X64_MSR_STIMER0_CONFIG   0x40B0
+#define HV_X64_MSR_STIMER0_COUNT0x40B1
+#define HV_X64_MSR_STIMER1_CONFIG   0x40B2
+#define HV_X64_MSR_STIMER1_COUNT0x40B3
+#define HV_X64_MSR_STIMER2_CONFIG   0x40B4
+#define HV_X64_MSR_STIMER2_COUNT0x40B5
+#define HV_X64_MSR_STIMER3_CONFIG   0x40B6
+#define HV_X64_MSR_STIMER3_COUNT0x40B7
+
 #define HV_SYNIC_CONTROL_ENABLE (1ULL << 0)
 #define HV_SYNIC_SIMP_ENABLE(1ULL << 0)
 #define HV_SYNIC_SIEFP_ENABLE   (1ULL << 0)
@@ -40,6 +57,104 @@
 #define HV_SYNIC_SINT_VECTOR_MASK   (0xFF)
 #define HV_SYNIC_SINT_COUNT 16
 
+#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)
+
+#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. */
+enum hv_message_type {
+HVMSG_NONE  = 0x,
+
+/* Memory access messages. */
+HVMSG_UNMAPPED_GPA  = 0x8000,
+HVMSG_GPA_INTERCEPT = 0x8001,
+
+/* Timer notification messages. */
+HVMSG_TIMER_EXPIRED = 0x8010,
+
+/* Error messages. */
+HVMSG_INVALID_VP_REGISTER_VALUE = 0x8020,
+HVMSG_UNRECOVERABLE_EXCEPTION   = 0x8021,
+HVMSG_UNSUPPORTED_FEATURE   = 0x8022,
+
+/* Trace buffer complete messages. */
+HVMSG_EVENTLOG_BUFFERCOMPLETE   = 0x8040,
+
+/* Platform-specific processor intercept messages. */
+HVMSG_X64_IOPORT_INTER

[Qemu-devel] [PATCH v1] kvm/x86: Remove Hyper-V SynIC timer stopping

2015-12-14 Thread Andrey Smetanin
It's possible that guest send us Hyper-V EOM at the middle
of Hyper-V SynIC timer running, so we start processing of Hyper-V
SynIC timers in vcpu context and stop the Hyper-V SynIC timer
uncoditionally and lose time expiration which Windows 2012R2 guest
expects.

The patch fixes such situation by not stopping Hyper-V SynIC timer
at all, because it's safe to restart it without stop in vcpu context
and timer callback always returns HRTIMER_NORESTART.

Signed-off-by: Andrey Smetanin 
CC: Gleb Natapov 
CC: Paolo Bonzini 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: qemu-devel@nongnu.org

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

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index 8ff8829..f34f666 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -598,7 +598,6 @@ void kvm_hv_process_stimers(struct kvm_vcpu *vcpu)
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)
-- 
2.4.3




Re: [Qemu-devel] [PATCH v1] kvm/x86: Remove Hyper-V SynIC timer stopping

2015-12-14 Thread Andrey Smetanin



On 12/14/2015 07:09 PM, Paolo Bonzini wrote:



On 14/12/2015 16:33, Andrey Smetanin wrote:

It's possible that guest send us Hyper-V EOM at the middle
of Hyper-V SynIC timer running, so we start processing of Hyper-V
SynIC timers in vcpu context and stop the Hyper-V SynIC timer
uncoditionally and lose time expiration which Windows 2012R2 guest
expects.

The patch fixes such situation by not stopping Hyper-V SynIC timer
at all, because it's safe to restart it without stop in vcpu context
and timer callback always returns HRTIMER_NORESTART.


Can you summarize with a "picture" what is the bad race?

hostguest
start periodic stimer
start periodic timer
timer expires after 15ms
send expiration message into guest
restart periodic timer
doing something
timer expires again after 15 ms
msg slot is still not cleared so
setup ->msg_pending
restart periodic timer
doing something
process timer msg and clear slot
so ->msg_pending was set:
send EOM into host
received EOM
queued call of kvm_hv_process_stimers()
by KVM_REQ_HV_STIMER

kvm_hv_process_stimers():
...
stimer_stop()
if (time_now >= stimer->exp_time)
stimer_expiration(stimer);
But time_now  < stimer->exp_time, so stimer_expiration is not called
in this case and timer is not restarted. so guest lose timer.


The patch seems safe, but I'd like to have a better understanding of
what goes wrong.

Paolo





Re: [Qemu-devel] [PATCH v1] kvm/x86: Remove Hyper-V SynIC timer stopping

2015-12-14 Thread Andrey Smetanin



On 12/14/2015 07:09 PM, Paolo Bonzini wrote:



On 14/12/2015 16:33, Andrey Smetanin wrote:

It's possible that guest send us Hyper-V EOM at the middle
of Hyper-V SynIC timer running, so we start processing of Hyper-V
SynIC timers in vcpu context and stop the Hyper-V SynIC timer
uncoditionally and lose time expiration which Windows 2012R2 guest
expects.

The patch fixes such situation by not stopping Hyper-V SynIC timer
at all, because it's safe to restart it without stop in vcpu context
and timer callback always returns HRTIMER_NORESTART.


Can you summarize with a "picture" what is the bad race?

Currently I see that guest starts periodic timer and doesn't clear 
message slot after timer expires, so timer expires again and trying to 
deliver expiration message but message slot is still busy so we set 
->msg_pending flag for guest to receive EOM. timer restarts again and 
while it's not expired guest notifies us with EOM, in this case we 
schedule timer processing in vcpu context by KVM_REQ_HV_STIMER, 
kvm_hv_process_stimers() is called in vcpu context and stops the timer

before it expires, so timer is disabled forever but guest expects it's
periodic expiration(15ms).

I do not understand why Windows doesn't clear message slot for a long 
time, it's likely need to be analyzed with debugger(and need more 
research). But we can go out from such situation by such fix.



The patch seems safe, but I'd like to have a better understanding of
what goes wrong.

Paolo





Re: [Qemu-devel] [PATCH v1] kvm/x86: Hyper-V tsc page setup

2016-01-11 Thread Andrey Smetanin

ping
On 12/24/2015 12:33 PM, Andrey Smetanin wrote:

Lately tsc page was implemented but filled with empty
values. This patch setup tsc page scale and offset based
on vcpu tsc, tsc_khz and  HV_X64_MSR_TIME_REF_COUNT value.

The valid tsc page drops HV_X64_MSR_TIME_REF_COUNT msr
reads count to zero which potentially improves performance.

The patch applies on top of
'kvm: Make vcpu->requests as 64 bit bitmap'
previously sent.

Signed-off-by: Andrey Smetanin 
CC: Paolo Bonzini 
CC: Gleb Natapov 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: qemu-devel@nongnu.org

---
  arch/x86/kvm/hyperv.c| 117 +--
  arch/x86/kvm/hyperv.h|   2 +
  arch/x86/kvm/x86.c   |  12 +
  include/linux/kvm_host.h |   1 +
  4 files changed, 117 insertions(+), 15 deletions(-)

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index d50675a..504fdc7 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -753,6 +753,105 @@ static int kvm_hv_msr_set_crash_data(struct kvm_vcpu 
*vcpu,
return 0;
  }
  
+static u64 calc_tsc_page_scale(u32 tsc_khz)

+{
+   /*
+* reftime (in 100ns) = tsc * tsc_scale / 2^64 + tsc_offset
+* so reftime_delta = (tsc_delta * tsc_scale) / 2^64
+* so tsc_scale = (2^64 * reftime_delta)/tsc_delta
+* so tsc_scale = (2^64 * 10 * 10^6) / tsc_hz = (2^64 * 1) / tsc_khz
+* so tsc_scale = (2^63 * 2 * 1) / tsc_khz
+*/
+   return mul_u64_u32_div(1ULL << 63, 2 * 1, tsc_khz);
+}
+
+static int write_tsc_page(struct kvm *kvm, u64 gfn,
+ PHV_REFERENCE_TSC_PAGE tsc_ref)
+{
+   if (kvm_write_guest(kvm, gfn_to_gpa(gfn),
+   tsc_ref, sizeof(*tsc_ref)))
+   return 1;
+   mark_page_dirty(kvm, gfn);
+   return 0;
+}
+
+static int read_tsc_page(struct kvm *kvm, u64 gfn,
+PHV_REFERENCE_TSC_PAGE tsc_ref)
+{
+   if (kvm_read_guest(kvm, gfn_to_gpa(gfn),
+  tsc_ref, sizeof(*tsc_ref)))
+   return 1;
+   return 0;
+}
+
+static u64 calc_tsc_page_time(struct kvm_vcpu *vcpu,
+ PHV_REFERENCE_TSC_PAGE tsc_ref)
+{
+
+   u64 tsc = kvm_read_l1_tsc(vcpu, rdtsc());
+
+   return mul_u64_u64_shr(tsc, tsc_ref->tsc_scale, 64)
+   + tsc_ref->tsc_offset;
+}
+
+static int setup_blank_tsc_page(struct kvm_vcpu *vcpu, u64 gfn)
+{
+   HV_REFERENCE_TSC_PAGE tsc_ref;
+
+   memset(&tsc_ref, 0, sizeof(tsc_ref));
+   return write_tsc_page(vcpu->kvm, gfn, &tsc_ref);
+}
+
+int kvm_hv_setup_tsc_page(struct kvm_vcpu *vcpu)
+{
+   struct kvm *kvm = vcpu->kvm;
+   struct kvm_hv *hv = &kvm->arch.hyperv;
+   HV_REFERENCE_TSC_PAGE tsc_ref;
+   u32 tsc_khz;
+   int r;
+   u64 gfn, ref_time, tsc_scale, tsc_offset, tsc;
+
+   if (WARN_ON_ONCE(!(hv->hv_tsc_page & HV_X64_MSR_TSC_REFERENCE_ENABLE)))
+   return -EINVAL;
+
+   gfn = hv->hv_tsc_page >> HV_X64_MSR_TSC_REFERENCE_ADDRESS_SHIFT;
+   vcpu_debug(vcpu, "tsc page gfn 0x%llx\n", gfn);
+
+   tsc_khz = vcpu->arch.virtual_tsc_khz;
+   if (!tsc_khz) {
+   vcpu_unimpl(vcpu, "no tsc khz\n");
+   return setup_blank_tsc_page(vcpu, gfn);
+   }
+
+   r = read_tsc_page(kvm, gfn, &tsc_ref);
+   if (r) {
+   vcpu_err(vcpu, "can't access tsc page gfn 0x%llx\n", gfn);
+   return r;
+   }
+
+   tsc_scale = calc_tsc_page_scale(tsc_khz);
+   ref_time = get_time_ref_counter(kvm);
+   tsc = kvm_read_l1_tsc(vcpu, rdtsc());
+
+   /* tsc_offset = reftime - tsc * tsc_scale / 2^64 */
+   tsc_offset = ref_time - mul_u64_u64_shr(tsc, tsc_scale, 64);
+   vcpu_debug(vcpu, "tsc khz %u tsc %llu scale %llu offset %llu\n",
+  tsc_khz, tsc, tsc_scale, tsc_offset);
+
+   tsc_ref.tsc_sequence++;
+   if (tsc_ref.tsc_sequence == 0)
+   tsc_ref.tsc_sequence = 1;
+
+   tsc_ref.tsc_scale = tsc_scale;
+   tsc_ref.tsc_offset = tsc_offset;
+
+   vcpu_debug(vcpu, "tsc page calibration time %llu vs. reftime %llu\n",
+  calc_tsc_page_time(vcpu, &tsc_ref),
+  get_time_ref_counter(kvm));
+
+   return write_tsc_page(kvm, gfn, &tsc_ref);
+}
+
  static int kvm_hv_set_msr_pw(struct kvm_vcpu *vcpu, u32 msr, u64 data,
 bool host)
  {
@@ -790,23 +889,11 @@ static int kvm_hv_set_msr_pw(struct kvm_vcpu *vcpu, u32 
msr, u64 data,
mark_page_dirty(kvm, gfn);
break;
}
-   case HV_X64_MSR_REFERENCE_TSC: {
-   u64 gfn;
-   HV_REFERENCE_TSC_PAGE tsc_ref;
-
-   memset(&tsc_ref, 0, sizeof(tsc_ref));
+   case HV_X64_MSR_REFERENCE_TSC:
hv->h

[Qemu-devel] [PATCH v1 3/5] kvm/x86: Pass return code of kvm_emulate_hypercall

2016-01-12 Thread Andrey Smetanin
Pass the return code from kvm_emulate_hypercall on to the caller,
in order to allow it to indicate to the userspace that
the hypercall has to be handled there.

Also adjust all the existing code paths to return 1 to make sure the
hypercall isn't passed to the userspace without setting kvm_run
appropriately.

Signed-off-by: Andrey Smetanin 
Reviewed-by: Roman Kagan 
CC: Gleb Natapov 
CC: Paolo Bonzini 
CC: Joerg Roedel 
CC: "K. Y. Srinivasan" 
CC: Haiyang Zhang 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: qemu-devel@nongnu.org
---
 arch/x86/kvm/hyperv.c | 2 +-
 arch/x86/kvm/svm.c| 3 +--
 arch/x86/kvm/vmx.c| 3 +--
 3 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index f1a42e1..0e7c90f 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -1055,7 +1055,7 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
 */
if (kvm_x86_ops->get_cpl(vcpu) != 0 || !is_protmode(vcpu)) {
kvm_queue_exception(vcpu, UD_VECTOR);
-   return 0;
+   return 1;
}
 
longmode = is_64_bit_mode(vcpu);
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index af34215..5fd8a5b 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -1858,8 +1858,7 @@ static int halt_interception(struct vcpu_svm *svm)
 static int vmmcall_interception(struct vcpu_svm *svm)
 {
svm->next_rip = kvm_rip_read(&svm->vcpu) + 3;
-   kvm_emulate_hypercall(&svm->vcpu);
-   return 1;
+   return kvm_emulate_hypercall(&svm->vcpu);
 }
 
 static unsigned long nested_svm_get_tdp_cr3(struct kvm_vcpu *vcpu)
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 62d958a..762c18e 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -5747,8 +5747,7 @@ static int handle_halt(struct kvm_vcpu *vcpu)
 
 static int handle_vmcall(struct kvm_vcpu *vcpu)
 {
-   kvm_emulate_hypercall(vcpu);
-   return 1;
+   return kvm_emulate_hypercall(vcpu);
 }
 
 static int handle_invd(struct kvm_vcpu *vcpu)
-- 
2.4.3




[Qemu-devel] [PATCH v1 1/5] kvm/x86: Rename Hyper-V long spin wait hypercall

2016-01-12 Thread Andrey Smetanin
Rename HV_X64_HV_NOTIFY_LONG_SPIN_WAIT
by HV_X64_HCALL_NOTIFY_LONG_SPIN_WAIT. So
the name better reflects hypercall codes accessory.

Signed-off-by: Andrey Smetanin 
Reviewed-by: Roman Kagan 
CC: Gleb Natapov 
CC: Paolo Bonzini 
CC: Joerg Roedel 
CC: "K. Y. Srinivasan" 
CC: Haiyang Zhang 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: qemu-devel@nongnu.org
---
 arch/x86/include/uapi/asm/hyperv.h | 2 +-
 arch/x86/kvm/hyperv.c  | 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 7956412..0c50fab 100644
--- a/arch/x86/include/uapi/asm/hyperv.h
+++ b/arch/x86/include/uapi/asm/hyperv.h
@@ -226,7 +226,7 @@
(~((1ull << HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_SHIFT) - 1))
 
 /* Declare the various hypercall operations. */
-#define HV_X64_HV_NOTIFY_LONG_SPIN_WAIT0x0008
+#define HV_X64_HCALL_NOTIFY_LONG_SPIN_WAIT 0x0008
 
 #define HV_X64_MSR_APIC_ASSIST_PAGE_ENABLE 0x0001
 #define HV_X64_MSR_APIC_ASSIST_PAGE_ADDRESS_SHIFT  12
diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index c58ba67..f1a42e1 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -1084,7 +1084,7 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
trace_kvm_hv_hypercall(code, fast, rep_cnt, rep_idx, ingpa, outgpa);
 
switch (code) {
-   case HV_X64_HV_NOTIFY_LONG_SPIN_WAIT:
+   case HV_X64_HCALL_NOTIFY_LONG_SPIN_WAIT:
kvm_vcpu_on_spin(vcpu);
break;
default:
-- 
2.4.3




[Qemu-devel] [PATCH v1 5/5] kvm/x86: Reject Hyper-V hypercall continuation

2016-01-12 Thread Andrey Smetanin
Currently we do not support Hyper-V hypercall continuation
so reject it.

Signed-off-by: Andrey Smetanin 
Reviewed-by: Roman Kagan 
CC: Gleb Natapov 
CC: Paolo Bonzini 
CC: Joerg Roedel 
CC: "K. Y. Srinivasan" 
CC: Haiyang Zhang 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: qemu-devel@nongnu.org
---
 arch/x86/kvm/hyperv.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index 76c9ec4..bc4884e 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -1083,6 +1083,12 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
 
trace_kvm_hv_hypercall(code, fast, rep_cnt, rep_idx, ingpa, outgpa);
 
+   /* Hypercall continuation is not supported yet */
+   if (rep_cnt || rep_idx) {
+   res = HV_STATUS_INVALID_HYPERCALL_CODE;
+   goto set_result;
+   }
+
switch (code) {
case HV_X64_HCALL_NOTIFY_LONG_SPIN_WAIT:
kvm_vcpu_on_spin(vcpu);
@@ -1099,6 +1105,7 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
break;
}
 
+set_result:
ret = res | (((u64)rep_done & 0xfff) << 32);
kvm_hv_hypercall_set_result(vcpu, ret);
return 1;
-- 
2.4.3




[Qemu-devel] [PATCH v1 4/5] kvm/x86: Hyper-V VMBus hypercall userspace exit

2016-01-12 Thread Andrey Smetanin
The patch implements KVM_EXIT_HV_HCALL functionality
for Hyper-V VMBus hypercalls: HV_X64_HCALL_POST_MESSAGE,
HV_X64_HCALL_SIGNAL_EVENT.

Signed-off-by: Andrey Smetanin 
Reviewed-by: Roman Kagan 
CC: Gleb Natapov 
CC: Paolo Bonzini 
CC: Joerg Roedel 
CC: "K. Y. Srinivasan" 
CC: Haiyang Zhang 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: qemu-devel@nongnu.org
---
 Documentation/virtual/kvm/api.txt |  8 
 arch/x86/kvm/hyperv.c | 28 +---
 arch/x86/kvm/hyperv.h |  1 +
 arch/x86/kvm/x86.c|  3 +++
 include/uapi/linux/kvm.h  |  7 +++
 5 files changed, 40 insertions(+), 7 deletions(-)

diff --git a/Documentation/virtual/kvm/api.txt 
b/Documentation/virtual/kvm/api.txt
index 053f613..23d4b9d 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -3359,6 +3359,14 @@ Hyper-V SynIC state change. Notification is used to 
remap SynIC
 event/message pages and to enable/disable SynIC messages/events processing
 in userspace.
 
+   /* KVM_EXIT_HYPERV_HCALL */
+   struct {
+   __u64 input;
+   __u64 params[2];
+   __u64 result;
+   } hv_hcall;
+Indicates that the VCPU exits into userspace to process some guest
+Hyper-V hypercalls.
/* Fix the size of the union. */
char padding[256];
};
diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index 0e7c90f..76c9ec4 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -1087,18 +1087,32 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
case HV_X64_HCALL_NOTIFY_LONG_SPIN_WAIT:
kvm_vcpu_on_spin(vcpu);
break;
+   case HV_X64_HCALL_POST_MESSAGE:
+   case HV_X64_HCALL_SIGNAL_EVENT:
+   vcpu->run->exit_reason = KVM_EXIT_HYPERV_HCALL;
+   vcpu->run->hv_hcall.input = param;
+   vcpu->run->hv_hcall.params[0] = ingpa;
+   vcpu->run->hv_hcall.params[1] = outgpa;
+   return 0;
default:
res = HV_STATUS_INVALID_HYPERCALL_CODE;
break;
}
 
ret = res | (((u64)rep_done & 0xfff) << 32);
-   if (longmode) {
-   kvm_register_write(vcpu, VCPU_REGS_RAX, ret);
-   } else {
-   kvm_register_write(vcpu, VCPU_REGS_RDX, ret >> 32);
-   kvm_register_write(vcpu, VCPU_REGS_RAX, ret & 0x);
-   }
-
+   kvm_hv_hypercall_set_result(vcpu, ret);
return 1;
 }
+
+void kvm_hv_hypercall_set_result(struct kvm_vcpu *vcpu, u64 result)
+{
+   bool longmode;
+
+   longmode = is_64_bit_mode(vcpu);
+   if (longmode)
+   kvm_register_write(vcpu, VCPU_REGS_RAX, result);
+   else {
+   kvm_register_write(vcpu, VCPU_REGS_RDX, result >> 32);
+   kvm_register_write(vcpu, VCPU_REGS_RAX, result & 0x);
+   }
+}
diff --git a/arch/x86/kvm/hyperv.h b/arch/x86/kvm/hyperv.h
index 60eccd4..64a4a3b 100644
--- a/arch/x86/kvm/hyperv.h
+++ b/arch/x86/kvm/hyperv.h
@@ -52,6 +52,7 @@ 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_hypercall_set_result(struct kvm_vcpu *vcpu, u64 result);
 
 void kvm_hv_irq_routing_update(struct kvm *kvm);
 int kvm_hv_synic_set_irq(struct kvm *kvm, u32 vcpu_id, u32 sint);
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index fad1d09..6ad3599 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -6886,6 +6886,9 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct 
kvm_run *kvm_run)
} else
WARN_ON(vcpu->arch.pio.count || vcpu->mmio_needed);
 
+   if (unlikely(kvm_run->exit_reason == KVM_EXIT_HYPERV_HCALL))
+   kvm_hv_hypercall_set_result(vcpu, kvm_run->hv_hcall.result);
+
r = vcpu_run(vcpu);
 
 out:
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 9da9051..a62c4fb 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -199,6 +199,7 @@ struct kvm_hyperv_exit {
 #define KVM_EXIT_S390_STSI25
 #define KVM_EXIT_IOAPIC_EOI   26
 #define KVM_EXIT_HYPERV   27
+#define KVM_EXIT_HYPERV_HCALL 28
 
 /* For KVM_EXIT_INTERNAL_ERROR */
 /* Emulate instruction failed. */
@@ -355,6 +356,12 @@ struct kvm_run {
} eoi;
/* KVM_EXIT_HYPERV */
struct kvm_hyperv_exit hyperv;
+   /* KVM_EXIT_HYPERV_HCALL */
+   struct {
+   __u64 input;
+   __u64 params[2];
+   __u64 result;
+   } hv_hcall;
/* Fix the size of the union. */
char padding[256];
};
-- 
2.4.3




[Qemu-devel] [PATCH v1 0/5] KVM: Hyper-V VMBus hypercalls

2016-01-12 Thread Andrey Smetanin
The patch implements userspace exit 'KVM_EXIT_HYPERV_HCALL'
for Hyper-V VMBus hypercalls(postmsg, signalevent)
to handle these hypercalls by QEMU.

Signed-off-by: Andrey Smetanin 
Reviewed-by: Roman Kagan 
CC: Gleb Natapov 
CC: Paolo Bonzini 
CC: Joerg Roedel 
CC: "K. Y. Srinivasan" 
CC: Haiyang Zhang 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: qemu-devel@nongnu.org

Andrey Smetanin (5):
  kvm/x86: Rename Hyper-V long spin wait hypercall
  drivers/hv: Move VMBus hypercall codes into Hyper-V UAPI header
  kvm/x86: Pass return code of kvm_emulate_hypercall
  kvm/x86: Hyper-V VMBus hypercall userspace exit
  kvm/x86: Reject Hyper-V hypercall continuation

 Documentation/virtual/kvm/api.txt  |  8 
 arch/x86/include/uapi/asm/hyperv.h |  4 +++-
 arch/x86/kvm/hyperv.c  | 39 +-
 arch/x86/kvm/hyperv.h  |  1 +
 arch/x86/kvm/svm.c |  3 +--
 arch/x86/kvm/vmx.c |  3 +--
 arch/x86/kvm/x86.c |  3 +++
 drivers/hv/hv.c|  5 +++--
 drivers/hv/hyperv_vmbus.h  |  6 --
 include/uapi/linux/kvm.h   |  7 +++
 10 files changed, 57 insertions(+), 22 deletions(-)

-- 
2.4.3




[Qemu-devel] [PATCH v1 2/5] drivers/hv: Move VMBus hypercall codes into Hyper-V UAPI header

2016-01-12 Thread Andrey Smetanin
VMBus hypercall codes inside Hyper-V UAPI header will
be used by QEMU to implement VMBus host devices support.

Signed-off-by: Andrey Smetanin 
Reviewed-by: Roman Kagan 
CC: Gleb Natapov 
CC: Paolo Bonzini 
CC: Joerg Roedel 
CC: "K. Y. Srinivasan" 
CC: Haiyang Zhang 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: qemu-devel@nongnu.org

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

diff --git a/arch/x86/include/uapi/asm/hyperv.h 
b/arch/x86/include/uapi/asm/hyperv.h
index 0c50fab..bc1c8a9 100644
--- a/arch/x86/include/uapi/asm/hyperv.h
+++ b/arch/x86/include/uapi/asm/hyperv.h
@@ -227,6 +227,8 @@
 
 /* Declare the various hypercall operations. */
 #define HV_X64_HCALL_NOTIFY_LONG_SPIN_WAIT 0x0008
+#define HV_X64_HCALL_POST_MESSAGE  0x005c
+#define HV_X64_HCALL_SIGNAL_EVENT  0x005d
 
 #define HV_X64_MSR_APIC_ASSIST_PAGE_ENABLE 0x0001
 #define HV_X64_MSR_APIC_ASSIST_PAGE_ADDRESS_SHIFT  12
diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
index 6341be8..56437d5 100644
--- a/drivers/hv/hv.c
+++ b/drivers/hv/hv.c
@@ -329,7 +329,7 @@ int hv_post_message(union hv_connection_id connection_id,
aligned_msg->payload_size = payload_size;
memcpy((void *)aligned_msg->payload, payload, payload_size);
 
-   status = do_hypercall(HVCALL_POST_MESSAGE, aligned_msg, NULL)
+   status = do_hypercall(HV_X64_HCALL_POST_MESSAGE, aligned_msg, NULL)
& 0x;
 
put_cpu();
@@ -347,7 +347,8 @@ u16 hv_signal_event(void *con_id)
 {
u16 status;
 
-   status = (do_hypercall(HVCALL_SIGNAL_EVENT, con_id, NULL) & 0x);
+   status = (do_hypercall(HV_X64_HCALL_SIGNAL_EVENT, con_id, NULL)
+ & 0x);
 
return status;
 }
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
index 678663e..36cad1f 100644
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -251,12 +251,6 @@ struct hv_monitor_page {
u8 rsvdz4[1984];
 };
 
-/* Declare the various hypercall operations. */
-enum hv_call_code {
-   HVCALL_POST_MESSAGE = 0x005c,
-   HVCALL_SIGNAL_EVENT = 0x005d,
-};
-
 /* Definition of the hv_post_message hypercall input structure. */
 struct hv_input_post_message {
union hv_connection_id connectionid;
-- 
2.4.3




[Qemu-devel] [PATCH v1] KVM-UNIT-TESTS:x86/hyperv: Hyper-V hypercalls test

2016-01-12 Thread Andrey Smetanin
This is a simple test which performs the
following:
* setup hypecall page
* do some hypercalls and output their results

Signed-off-by: Andrey Smetanin 
CC: Paolo Bonzini 
CC: Marcelo Tosatti 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: qemu-devel@nongnu.org
---
 config/config-x86-common.mak |  4 ++
 lib/x86/vm.h |  2 +
 x86/hyperv.c | 95 ++
 x86/hyperv.h | 28 +
 x86/hyperv_hypercall.c   | 99 
 x86/unittests.cfg|  5 +++
 6 files changed, 233 insertions(+)
 create mode 100644 x86/hyperv_hypercall.c

diff --git a/config/config-x86-common.mak b/config/config-x86-common.mak
index 72b95e3..11714d6 100644
--- a/config/config-x86-common.mak
+++ b/config/config-x86-common.mak
@@ -38,6 +38,7 @@ tests-common = $(TEST_DIR)/vmexit.flat $(TEST_DIR)/tsc.flat \
$(TEST_DIR)/tsc_adjust.flat $(TEST_DIR)/asyncpf.flat \
$(TEST_DIR)/init.flat $(TEST_DIR)/smap.flat \
$(TEST_DIR)/hyperv_synic.flat $(TEST_DIR)/hyperv_stimer.flat \
+   $(TEST_DIR)/hyperv_hypercall.flat \
 
 ifdef API
 tests-common += api/api-sample
@@ -119,6 +120,9 @@ $(TEST_DIR)/hyperv_synic.elf: $(cstart.o) 
$(TEST_DIR)/hyperv.o \
 $(TEST_DIR)/hyperv_stimer.elf: $(cstart.o) $(TEST_DIR)/hyperv.o \
$(TEST_DIR)/hyperv_stimer.o
 
+$(TEST_DIR)/hyperv_hypercall.elf: $(cstart.o) $(TEST_DIR)/hyperv.o \
+  $(TEST_DIR)/hyperv_hypercall.o
+
 arch_clean:
$(RM) $(TEST_DIR)/*.o $(TEST_DIR)/*.flat $(TEST_DIR)/*.elf \
$(TEST_DIR)/.*.d lib/x86/.*.d
diff --git a/lib/x86/vm.h b/lib/x86/vm.h
index 28794d7..085e29f 100644
--- a/lib/x86/vm.h
+++ b/lib/x86/vm.h
@@ -4,6 +4,8 @@
 #include "processor.h"
 
 #define PAGE_SIZE 4096ul
+#define PAGE_SHIFT 12
+
 #ifdef __x86_64__
 #define LARGE_PAGE_SIZE (512 * PAGE_SIZE)
 #else
diff --git a/x86/hyperv.c b/x86/hyperv.c
index 824773d..1d3ab23 100644
--- a/x86/hyperv.c
+++ b/x86/hyperv.c
@@ -1,4 +1,5 @@
 #include "hyperv.h"
+#include "vm.h"
 
 static void synic_ctl(u8 ctl, u8 vcpu_id, u8 sint)
 {
@@ -22,3 +23,97 @@ void synic_sint_destroy(int vcpu, int sint)
 wrmsr(HV_X64_MSR_SINT0 + sint, 0xFF|HV_SYNIC_SINT_MASKED);
 synic_ctl(HV_TEST_DEV_SINT_ROUTE_DESTROY, vcpu, sint);
 }
+
+static void *hv_hypercall_page;
+
+static inline u64 generate_guest_id(u8 d_info1, u32 kernel_version,
+u16 d_info2)
+{
+u64 guest_id = 0;
+
+guest_id = (((u64)HV_LINUX_VENDOR_ID) << 48);
+guest_id |= (((u64)(d_info1)) << 48);
+guest_id |= (((u64)(kernel_version)) << 16);
+guest_id |= ((u64)(d_info2));
+
+return guest_id;
+}
+
+int hv_hypercall_init(void)
+{
+void *page;
+u64 val;
+
+wrmsr(HV_X64_MSR_GUEST_OS_ID, generate_guest_id(0, 263168, 0));
+page = alloc_page();
+if (!page) {
+return -1;
+}
+
+wrmsr(HV_X64_MSR_HYPERCALL,
+  ((virt_to_phys(page) >> PAGE_SHIFT) <<
+  HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_SHIFT) |
+  HV_X64_MSR_HYPERCALL_ENABLE);
+
+val = rdmsr(HV_X64_MSR_HYPERCALL);
+if (!(val & HV_X64_MSR_HYPERCALL_ENABLE)) {
+goto err;
+}
+
+hv_hypercall_page = page;
+return 0;
+err:
+free_page(page);
+return -1;
+}
+
+void hv_hypercall_deinit(void)
+{
+wrmsr(HV_X64_MSR_HYPERCALL, 0);
+free_page(hv_hypercall_page);
+wrmsr(HV_X64_MSR_GUEST_OS_ID, 0);
+hv_hypercall_page = NULL;
+}
+
+u64 hv_hypercall(u64 control, void *input, void *output)
+{
+u64 input_address = (input) ? virt_to_phys(input) : 0;
+u64 output_address = (output) ? virt_to_phys(output) : 0;
+#ifdef __x86_64__
+u64 hv_status = 0;
+
+if (!hv_hypercall_page) {
+return (u64)-1;
+}
+
+__asm__ __volatile__("mov %0, %%r8" : : "r" (output_address) : "r8");
+__asm__ __volatile__("call *%3" : "=a" (hv_status) :
+ "c" (control), "d" (input_address),
+ "m" (hv_hypercall_page));
+
+return hv_status;
+
+#else
+
+u32 control_hi = control >> 32;
+u32 control_lo = control & 0x;
+u32 hv_status_hi = 1;
+u32 hv_status_lo = 1;
+u32 input_address_hi = input_address >> 32;
+u32 input_address_lo = input_address & 0x;
+u32 output_address_hi = output_address >> 32;
+u32 output_address_lo = output_address & 0x;
+
+if (!hv_hypercall_page) {
+return (u64)-1;
+}
+
+__asm__ __volatile__ ("call *%8" : "=d"(hv_status_hi),
+  "=a"(hv_status_lo) : "d" (control_

[Qemu-devel] [PATCH v1 1/2] headers: Hyper-V VMBus hypercall codes and exit

2016-01-12 Thread Andrey Smetanin
This patch just for completeness, this changes
should be received by scripts/update-linux-headers.sh

Signed-off-by: Andrey Smetanin 
Reviewed-by: Roman Kagan 
CC: Paolo Bonzini 
CC: Richard Henderson 
CC: Eduardo Habkost 
CC: "Andreas Färber" 
CC: Marcelo Tosatti 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: k...@vger.kernel.org

---
 include/standard-headers/asm-x86/hyperv.h | 4 +++-
 linux-headers/linux/kvm.h | 7 +++
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/include/standard-headers/asm-x86/hyperv.h 
b/include/standard-headers/asm-x86/hyperv.h
index acb119d..27b445e 100644
--- a/include/standard-headers/asm-x86/hyperv.h
+++ b/include/standard-headers/asm-x86/hyperv.h
@@ -226,7 +226,9 @@
(~((1ull << HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_SHIFT) - 1))
 
 /* Declare the various hypercall operations. */
-#define HV_X64_HV_NOTIFY_LONG_SPIN_WAIT0x0008
+#define HV_X64_HCALL_NOTIFY_LONG_SPIN_WAIT 0x0008
+#define HV_X64_HCALL_POST_MESSAGE  0x005c
+#define HV_X64_HCALL_SIGNAL_EVENT  0x005d
 
 #define HV_X64_MSR_APIC_ASSIST_PAGE_ENABLE 0x0001
 #define HV_X64_MSR_APIC_ASSIST_PAGE_ADDRESS_SHIFT  12
diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
index 4e20262..32879ba 100644
--- a/linux-headers/linux/kvm.h
+++ b/linux-headers/linux/kvm.h
@@ -199,6 +199,7 @@ struct kvm_hyperv_exit {
 #define KVM_EXIT_S390_STSI25
 #define KVM_EXIT_IOAPIC_EOI   26
 #define KVM_EXIT_HYPERV   27
+#define KVM_EXIT_HYPERV_HCALL 28
 
 /* For KVM_EXIT_INTERNAL_ERROR */
 /* Emulate instruction failed. */
@@ -355,6 +356,12 @@ struct kvm_run {
} eoi;
/* KVM_EXIT_HYPERV */
struct kvm_hyperv_exit hyperv;
+   /* KVM_EXIT_HYPERV_HCALL */
+   struct {
+   __u64 input;
+   __u64 params[2];
+   __u64 result;
+   } hv_hcall;
/* Fix the size of the union. */
char padding[256];
};
-- 
2.4.3




[Qemu-devel] [PATCH v1 0/2] QEMU: Hyper-V VMBus hypercalls blank handlers

2016-01-12 Thread Andrey Smetanin
The patches adds blank handlers for Hyper-V
VMBus hypercalls routed by KVM_EXIT_HYPERV_HCALL KVM exit.

Signed-off-by: Andrey Smetanin 
Reviewed-by: Roman Kagan 
CC: Paolo Bonzini 
CC: Richard Henderson 
CC: Eduardo Habkost 
CC: "Andreas Färber" 
CC: Marcelo Tosatti 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: k...@vger.kernel.org

Andrey Smetanin (2):
  headers: Hyper-V VMBus hypercall codes and exit
  target-i386/kvm: Hyper-V VMBus hypercalls blank handlers

 include/standard-headers/asm-x86/hyperv.h |  4 +++-
 linux-headers/linux/kvm.h |  7 +++
 target-i386/hyperv.c  | 14 ++
 target-i386/hyperv.h  |  2 ++
 target-i386/kvm.c |  3 +++
 5 files changed, 29 insertions(+), 1 deletion(-)

-- 
2.4.3




[Qemu-devel] [PATCH v1 2/2] target-i386/kvm: Hyper-V VMBus hypercalls blank handlers

2016-01-12 Thread Andrey Smetanin
Add Hyper-V VMBus hypercalls blank handlers which
just returns error code - HV_STATUS_INVALID_HYPERCALL_CODE.

Signed-off-by: Andrey Smetanin 
Reviewed-by: Roman Kagan 
CC: Paolo Bonzini 
CC: Richard Henderson 
CC: Eduardo Habkost 
CC: "Andreas Färber" 
CC: Marcelo Tosatti 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: k...@vger.kernel.org
---
 target-i386/hyperv.c | 14 ++
 target-i386/hyperv.h |  2 ++
 target-i386/kvm.c|  3 +++
 3 files changed, 19 insertions(+)

diff --git a/target-i386/hyperv.c b/target-i386/hyperv.c
index e79b173..bd09506 100644
--- a/target-i386/hyperv.c
+++ b/target-i386/hyperv.c
@@ -125,3 +125,17 @@ int kvm_hv_sint_route_set_sint(HvSintRoute *sint_route)
 {
 return event_notifier_set(&sint_route->sint_set_notifier);
 }
+
+int kvm_hv_handle_hypercall(X86CPU *cpu, struct kvm_run *run)
+{
+uint16_t code;
+
+code  = run->hv_hcall.input & 0x;
+switch (code) {
+case HV_X64_HCALL_POST_MESSAGE:
+case HV_X64_HCALL_SIGNAL_EVENT:
+default:
+run->hv_hcall.result = HV_STATUS_INVALID_HYPERCALL_CODE;
+return 0;
+}
+}
diff --git a/target-i386/hyperv.h b/target-i386/hyperv.h
index b26201f..9515b6e 100644
--- a/target-i386/hyperv.h
+++ b/target-i386/hyperv.h
@@ -39,4 +39,6 @@ void kvm_hv_sint_route_destroy(HvSintRoute *sint_route);
 
 int kvm_hv_sint_route_set_sint(HvSintRoute *sint_route);
 
+int kvm_hv_handle_hypercall(X86CPU *cpu, struct kvm_run *run);
+
 #endif
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index ab65a6e..adb1d64 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -3026,6 +3026,9 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run 
*run)
 ioapic_eoi_broadcast(run->eoi.vector);
 ret = 0;
 break;
+case KVM_EXIT_HYPERV_HCALL:
+ret = kvm_hv_handle_hypercall(cpu, run);
+break;
 default:
 fprintf(stderr, "KVM: unknown exit reason %d\n", run->exit_reason);
 ret = -1;
-- 
2.4.3




Re: [Qemu-devel] [PATCH v1 0/5] KVM: Hyper-V VMBus hypercalls

2016-01-12 Thread Andrey Smetanin

Paolo,

Could you please force these patches applied
during current merge window. We need them
very, because they are last patches for KVM which
are required to start development of Hyper-V
VMBus devices in QEMU side.

P.S.:
We have created our public repo (based on current kvm/queue) to fetch
our latest changes in KVM code to support Hyper-V VMBus:

https://src.openvz.org/projects/UP/repos/kvm_hyperv/commits?until=refs%2Fheads%2Fvmbus_hypercall

Thanks,
Andrey

On 01/12/2016 01:50 PM, Andrey Smetanin wrote:


The patch implements userspace exit 'KVM_EXIT_HYPERV_HCALL'
for Hyper-V VMBus hypercalls(postmsg, signalevent)
to handle these hypercalls by QEMU.

Signed-off-by: Andrey Smetanin 
Reviewed-by: Roman Kagan 
CC: Gleb Natapov 
CC: Paolo Bonzini 
CC: Joerg Roedel 
CC: "K. Y. Srinivasan" 
CC: Haiyang Zhang 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: qemu-devel@nongnu.org

Andrey Smetanin (5):
   kvm/x86: Rename Hyper-V long spin wait hypercall
   drivers/hv: Move VMBus hypercall codes into Hyper-V UAPI header
   kvm/x86: Pass return code of kvm_emulate_hypercall
   kvm/x86: Hyper-V VMBus hypercall userspace exit
   kvm/x86: Reject Hyper-V hypercall continuation

  Documentation/virtual/kvm/api.txt  |  8 
  arch/x86/include/uapi/asm/hyperv.h |  4 +++-
  arch/x86/kvm/hyperv.c  | 39 +-
  arch/x86/kvm/hyperv.h  |  1 +
  arch/x86/kvm/svm.c |  3 +--
  arch/x86/kvm/vmx.c |  3 +--
  arch/x86/kvm/x86.c |  3 +++
  drivers/hv/hv.c|  5 +++--
  drivers/hv/hyperv_vmbus.h  |  6 --
  include/uapi/linux/kvm.h   |  7 +++
  10 files changed, 57 insertions(+), 22 deletions(-)






Re: [Qemu-devel] [PATCH v1] kvm/x86: Hyper-V tsc page setup

2016-01-20 Thread Andrey Smetanin



On 01/20/2016 05:05 PM, Paolo Bonzini wrote:



On 19/01/2016 08:48, Denis V. Lunev wrote:


diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 6877b4d7e..93c9e25 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -145,6 +145,7 @@ static inline bool is_error_page(struct page *page)
   #define KVM_REQ_HV_RESET  29
   #define KVM_REQ_HV_EXIT   30
   #define KVM_REQ_HV_STIMER 31
+#define KVM_REQ_HV_TSC_PAGE   32
 #define KVM_REQ_MAX   64


ping


Applied with this change:

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index d7716c6e2752..047c275717d3 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -842,7 +842,7 @@ int kvm_hv_setup_tsc_page(struct kvm_vcpu *vcpu)
   tsc_khz, tsc, tsc_scale, tsc_offset);

tsc_ref.tsc_sequence++;
-   if (tsc_ref.tsc_sequence == 0)
+   if (tsc_ref.tsc_sequence == 0x tsc_ref.tsc_sequence == 0)

"(tsc_ref.tsc_sequence == 0x || tsc_ref.tsc_sequence == 0)" ?

tsc_ref.tsc_sequence = 1;

tsc_ref.tsc_scale = tsc_scale;

and renumbering KVM_REQ_HV_TSC_PAGE from 32 to 31.

Paolo





[Qemu-devel] [PATCH v2 3/5] kvm/x86: Pass return code of kvm_emulate_hypercall

2016-01-21 Thread Andrey Smetanin
Pass the return code from kvm_emulate_hypercall on to the caller,
in order to allow it to indicate to the userspace that
the hypercall has to be handled there.

Also adjust all the existing code paths to return 1 to make sure the
hypercall isn't passed to the userspace without setting kvm_run
appropriately.

Signed-off-by: Andrey Smetanin 
Reviewed-by: Roman Kagan 
CC: Gleb Natapov 
CC: Paolo Bonzini 
CC: Joerg Roedel 
CC: "K. Y. Srinivasan" 
CC: Haiyang Zhang 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: qemu-devel@nongnu.org
---
 arch/x86/kvm/hyperv.c | 2 +-
 arch/x86/kvm/svm.c| 3 +--
 arch/x86/kvm/vmx.c| 3 +--
 3 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index f1a42e1..0e7c90f 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -1055,7 +1055,7 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
 */
if (kvm_x86_ops->get_cpl(vcpu) != 0 || !is_protmode(vcpu)) {
kvm_queue_exception(vcpu, UD_VECTOR);
-   return 0;
+   return 1;
}
 
longmode = is_64_bit_mode(vcpu);
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index c13a64b..9507038 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -1858,8 +1858,7 @@ static int halt_interception(struct vcpu_svm *svm)
 static int vmmcall_interception(struct vcpu_svm *svm)
 {
svm->next_rip = kvm_rip_read(&svm->vcpu) + 3;
-   kvm_emulate_hypercall(&svm->vcpu);
-   return 1;
+   return kvm_emulate_hypercall(&svm->vcpu);
 }
 
 static unsigned long nested_svm_get_tdp_cr3(struct kvm_vcpu *vcpu)
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 04d61d4..82879aa 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -5747,8 +5747,7 @@ static int handle_halt(struct kvm_vcpu *vcpu)
 
 static int handle_vmcall(struct kvm_vcpu *vcpu)
 {
-   kvm_emulate_hypercall(vcpu);
-   return 1;
+   return kvm_emulate_hypercall(vcpu);
 }
 
 static int handle_invd(struct kvm_vcpu *vcpu)
-- 
2.4.3




[Qemu-devel] [PATCH v2 4/5] kvm/x86: Reject Hyper-V hypercall continuation

2016-01-21 Thread Andrey Smetanin
Currently we do not support Hyper-V hypercall continuation
so reject it.

Signed-off-by: Andrey Smetanin 
Reviewed-by: Roman Kagan 
CC: Gleb Natapov 
CC: Paolo Bonzini 
CC: Joerg Roedel 
CC: "K. Y. Srinivasan" 
CC: Haiyang Zhang 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: qemu-devel@nongnu.org
---
 arch/x86/kvm/hyperv.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index 0e7c90f..e1daa8b 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -1083,6 +1083,12 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
 
trace_kvm_hv_hypercall(code, fast, rep_cnt, rep_idx, ingpa, outgpa);
 
+   /* Hypercall continuation is not supported yet */
+   if (rep_cnt || rep_idx) {
+   res = HV_STATUS_INVALID_HYPERCALL_CODE;
+   goto set_result;
+   }
+
switch (code) {
case HV_X64_HCALL_NOTIFY_LONG_SPIN_WAIT:
kvm_vcpu_on_spin(vcpu);
@@ -1092,6 +1098,7 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
break;
}
 
+set_result:
ret = res | (((u64)rep_done & 0xfff) << 32);
if (longmode) {
kvm_register_write(vcpu, VCPU_REGS_RAX, ret);
-- 
2.4.3




[Qemu-devel] [PATCH v2 2/5] drivers/hv: Move VMBus hypercall codes into Hyper-V UAPI header

2016-01-21 Thread Andrey Smetanin
VMBus hypercall codes inside Hyper-V UAPI header will
be used by QEMU to implement VMBus host devices support.

Signed-off-by: Andrey Smetanin 
Acked-by: K. Y. Srinivasan 
Reviewed-by: Roman Kagan 
CC: Gleb Natapov 
CC: Paolo Bonzini 
CC: Joerg Roedel 
CC: "K. Y. Srinivasan" 
CC: Haiyang Zhang 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: qemu-devel@nongnu.org
---
 arch/x86/include/uapi/asm/hyperv.h | 2 ++
 drivers/hv/hv.c| 4 ++--
 drivers/hv/hyperv_vmbus.h  | 6 --
 3 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/arch/x86/include/uapi/asm/hyperv.h 
b/arch/x86/include/uapi/asm/hyperv.h
index 0c50fab..bc1c8a9 100644
--- a/arch/x86/include/uapi/asm/hyperv.h
+++ b/arch/x86/include/uapi/asm/hyperv.h
@@ -227,6 +227,8 @@
 
 /* Declare the various hypercall operations. */
 #define HV_X64_HCALL_NOTIFY_LONG_SPIN_WAIT 0x0008
+#define HV_X64_HCALL_POST_MESSAGE  0x005c
+#define HV_X64_HCALL_SIGNAL_EVENT  0x005d
 
 #define HV_X64_MSR_APIC_ASSIST_PAGE_ENABLE 0x0001
 #define HV_X64_MSR_APIC_ASSIST_PAGE_ADDRESS_SHIFT  12
diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
index 11bca51..5ce2dec 100644
--- a/drivers/hv/hv.c
+++ b/drivers/hv/hv.c
@@ -331,7 +331,7 @@ int hv_post_message(union hv_connection_id connection_id,
aligned_msg->payload_size = payload_size;
memcpy((void *)aligned_msg->payload, payload, payload_size);
 
-   status = hv_do_hypercall(HVCALL_POST_MESSAGE, aligned_msg, NULL);
+   status = hv_do_hypercall(HV_X64_HCALL_POST_MESSAGE, aligned_msg, NULL);
 
put_cpu();
return status & 0x;
@@ -348,7 +348,7 @@ int hv_signal_event(void *con_id)
 {
u64 status;
 
-   status = hv_do_hypercall(HVCALL_SIGNAL_EVENT, con_id, NULL);
+   status = hv_do_hypercall(HV_X64_HCALL_SIGNAL_EVENT, con_id, NULL);
 
return status & 0x;
 }
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
index 4ebc796..2f8c0f4 100644
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -256,12 +256,6 @@ struct hv_monitor_page {
u8 rsvdz4[1984];
 };
 
-/* Declare the various hypercall operations. */
-enum hv_call_code {
-   HVCALL_POST_MESSAGE = 0x005c,
-   HVCALL_SIGNAL_EVENT = 0x005d,
-};
-
 /* Definition of the hv_post_message hypercall input structure. */
 struct hv_input_post_message {
union hv_connection_id connectionid;
-- 
2.4.3




[Qemu-devel] [PATCH v2 1/5] kvm/x86: Rename Hyper-V long spin wait hypercall

2016-01-21 Thread Andrey Smetanin
Rename HV_X64_HV_NOTIFY_LONG_SPIN_WAIT
by HV_X64_HCALL_NOTIFY_LONG_SPIN_WAIT. So
the name better reflects hypercall codes accessory.

Signed-off-by: Andrey Smetanin 
Reviewed-by: Roman Kagan 
CC: Gleb Natapov 
CC: Paolo Bonzini 
CC: Joerg Roedel 
CC: "K. Y. Srinivasan" 
CC: Haiyang Zhang 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: qemu-devel@nongnu.org
---
 arch/x86/include/uapi/asm/hyperv.h | 2 +-
 arch/x86/kvm/hyperv.c  | 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 7956412..0c50fab 100644
--- a/arch/x86/include/uapi/asm/hyperv.h
+++ b/arch/x86/include/uapi/asm/hyperv.h
@@ -226,7 +226,7 @@
(~((1ull << HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_SHIFT) - 1))
 
 /* Declare the various hypercall operations. */
-#define HV_X64_HV_NOTIFY_LONG_SPIN_WAIT0x0008
+#define HV_X64_HCALL_NOTIFY_LONG_SPIN_WAIT 0x0008
 
 #define HV_X64_MSR_APIC_ASSIST_PAGE_ENABLE 0x0001
 #define HV_X64_MSR_APIC_ASSIST_PAGE_ADDRESS_SHIFT  12
diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index c58ba67..f1a42e1 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -1084,7 +1084,7 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
trace_kvm_hv_hypercall(code, fast, rep_cnt, rep_idx, ingpa, outgpa);
 
switch (code) {
-   case HV_X64_HV_NOTIFY_LONG_SPIN_WAIT:
+   case HV_X64_HCALL_NOTIFY_LONG_SPIN_WAIT:
kvm_vcpu_on_spin(vcpu);
break;
default:
-- 
2.4.3




[Qemu-devel] [PATCH v2 0/5] KVM: Hyper-V VMBus hypercalls

2016-01-21 Thread Andrey Smetanin
The patch implements userspace exit 'KVM_EXIT_HYPERV'
for Hyper-V VMBus hypercalls(postmsg, signalevent)
to handle these hypercalls by QEMU.

Changes v2:
* use KVM_EXIT_HYPERV for hypercalls

Signed-off-by: Andrey Smetanin 
Reviewed-by: Roman Kagan 
CC: Gleb Natapov 
CC: Paolo Bonzini 
CC: Joerg Roedel 
CC: "K. Y. Srinivasan" 
CC: Haiyang Zhang 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: qemu-devel@nongnu.org

Andrey Smetanin (5):
  kvm/x86: Rename Hyper-V long spin wait hypercall
  drivers/hv: Move VMBus hypercall codes into Hyper-V UAPI header
  kvm/x86: Pass return code of kvm_emulate_hypercall
  kvm/x86: Reject Hyper-V hypercall continuation
  kvm/x86: Hyper-V VMBus hypercall userspace exit

 Documentation/virtual/kvm/api.txt  |  6 ++
 arch/x86/include/uapi/asm/hyperv.h |  4 +++-
 arch/x86/kvm/hyperv.c  | 40 +-
 arch/x86/kvm/hyperv.h  |  1 +
 arch/x86/kvm/svm.c |  3 +--
 arch/x86/kvm/vmx.c |  3 +--
 arch/x86/kvm/x86.c |  5 +
 drivers/hv/hv.c|  4 ++--
 drivers/hv/hyperv_vmbus.h  |  6 --
 include/uapi/linux/kvm.h   |  6 ++
 10 files changed, 56 insertions(+), 22 deletions(-)

-- 
2.4.3




[Qemu-devel] [PATCH v2 5/5] kvm/x86: Hyper-V VMBus hypercall userspace exit

2016-01-21 Thread Andrey Smetanin
The patch implements KVM_EXIT_HYPERV userspace exit
functionality for Hyper-V VMBus hypercalls:
HV_X64_HCALL_POST_MESSAGE, HV_X64_HCALL_SIGNAL_EVENT.

Changes v2:
* use KVM_EXIT_HYPERV for hypercalls

Signed-off-by: Andrey Smetanin 
Reviewed-by: Roman Kagan 
CC: Gleb Natapov 
CC: Paolo Bonzini 
CC: Joerg Roedel 
CC: "K. Y. Srinivasan" 
CC: Haiyang Zhang 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: qemu-devel@nongnu.org
---
 Documentation/virtual/kvm/api.txt |  6 ++
 arch/x86/kvm/hyperv.c | 29 ++---
 arch/x86/kvm/hyperv.h |  1 +
 arch/x86/kvm/x86.c|  5 +
 include/uapi/linux/kvm.h  |  6 ++
 5 files changed, 40 insertions(+), 7 deletions(-)

diff --git a/Documentation/virtual/kvm/api.txt 
b/Documentation/virtual/kvm/api.txt
index 053f613..1bf1a07 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -3339,6 +3339,7 @@ EOI was received.
 
struct kvm_hyperv_exit {
 #define KVM_EXIT_HYPERV_SYNIC  1
+#define KVM_EXIT_HYPERV_HCALL  2
__u32 type;
union {
struct {
@@ -3347,6 +3348,11 @@ EOI was received.
__u64 evt_page;
__u64 msg_page;
} synic;
+   struct {
+   __u64 input;
+   __u64 result;
+   __u64 params[2];
+   } hcall;
} u;
};
/* KVM_EXIT_HYPERV */
diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index e1daa8b..26ae973 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -1093,6 +1093,14 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
case HV_X64_HCALL_NOTIFY_LONG_SPIN_WAIT:
kvm_vcpu_on_spin(vcpu);
break;
+   case HV_X64_HCALL_POST_MESSAGE:
+   case HV_X64_HCALL_SIGNAL_EVENT:
+   vcpu->run->exit_reason = KVM_EXIT_HYPERV;
+   vcpu->run->hyperv.type = KVM_EXIT_HYPERV_HCALL;
+   vcpu->run->hyperv.u.hcall.input = param;
+   vcpu->run->hyperv.u.hcall.params[0] = ingpa;
+   vcpu->run->hyperv.u.hcall.params[1] = outgpa;
+   return 0;
default:
res = HV_STATUS_INVALID_HYPERCALL_CODE;
break;
@@ -1100,12 +1108,19 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
 
 set_result:
ret = res | (((u64)rep_done & 0xfff) << 32);
-   if (longmode) {
-   kvm_register_write(vcpu, VCPU_REGS_RAX, ret);
-   } else {
-   kvm_register_write(vcpu, VCPU_REGS_RDX, ret >> 32);
-   kvm_register_write(vcpu, VCPU_REGS_RAX, ret & 0x);
-   }
-
+   kvm_hv_hypercall_set_result(vcpu, ret);
return 1;
 }
+
+void kvm_hv_hypercall_set_result(struct kvm_vcpu *vcpu, u64 result)
+{
+   bool longmode;
+
+   longmode = is_64_bit_mode(vcpu);
+   if (longmode)
+   kvm_register_write(vcpu, VCPU_REGS_RAX, result);
+   else {
+   kvm_register_write(vcpu, VCPU_REGS_RDX, result >> 32);
+   kvm_register_write(vcpu, VCPU_REGS_RAX, result & 0x);
+   }
+}
diff --git a/arch/x86/kvm/hyperv.h b/arch/x86/kvm/hyperv.h
index 60eccd4..64a4a3b 100644
--- a/arch/x86/kvm/hyperv.h
+++ b/arch/x86/kvm/hyperv.h
@@ -52,6 +52,7 @@ 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_hypercall_set_result(struct kvm_vcpu *vcpu, u64 result);
 
 void kvm_hv_irq_routing_update(struct kvm *kvm);
 int kvm_hv_synic_set_irq(struct kvm *kvm, u32 vcpu_id, u32 sint);
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index f53f5b1..e5c842b 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -6891,6 +6891,11 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, 
struct kvm_run *kvm_run)
} else
WARN_ON(vcpu->arch.pio.count || vcpu->mmio_needed);
 
+   if (unlikely(kvm_run->exit_reason == KVM_EXIT_HYPERV) &&
+   kvm_run->hyperv.type == KVM_EXIT_HYPERV_HCALL)
+   kvm_hv_hypercall_set_result(vcpu,
+   kvm_run->hyperv.u.hcall.result);
+
r = vcpu_run(vcpu);
 
 out:
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 9da9051..c5519a9 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -157,6 +157,7 @@ struct kvm_s390_skeys {
 
 struct kvm_hyperv_exit {
 #define KVM_EXIT_HYPERV_SYNIC  1
+#define KVM_EXIT_HYPERV_HCALL  2
__u32 type;
union {
   

[Qemu-devel] [PATCH v2] target-i386/kvm: Hyper-V VMBus hypercalls blank handlers

2016-01-21 Thread Andrey Smetanin
Add Hyper-V VMBus hypercalls blank handlers which
just returns error code - HV_STATUS_INVALID_HYPERCALL_CODE.

Changes v2:
* use KVM_EXIT_HYPERV exit type

Signed-off-by: Andrey Smetanin 
Reviewed-by: Roman Kagan 
CC: Paolo Bonzini 
CC: Richard Henderson 
CC: Eduardo Habkost 
CC: "Andreas Färber" 
CC: Marcelo Tosatti 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: k...@vger.kernel.org

---
 target-i386/hyperv.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/target-i386/hyperv.c b/target-i386/hyperv.c
index e79b173..d3f3059 100644
--- a/target-i386/hyperv.c
+++ b/target-i386/hyperv.c
@@ -43,6 +43,18 @@ int kvm_hv_handle_exit(X86CPU *cpu, struct kvm_hyperv_exit 
*exit)
 return -1;
 }
 return 0;
+case KVM_EXIT_HYPERV_HCALL: {
+uint16_t code;
+
+code  = exit->u.hcall.input & 0x;
+switch (code) {
+case HV_X64_HCALL_POST_MESSAGE:
+case HV_X64_HCALL_SIGNAL_EVENT:
+default:
+exit->u.hcall.result = HV_STATUS_INVALID_HYPERCALL_CODE;
+return 0;
+}
+}
 default:
 return -1;
 }
-- 
2.4.3




Re: [Qemu-devel] [PATCH v4 5/5] kvm/x86: Hyper-V kvm exit

2015-12-21 Thread Andrey Smetanin



On 12/18/2015 09:39 PM, Roman Kagan wrote:

On Fri, Dec 18, 2015 at 10:10:11AM -0800, Peter Hornyack wrote:

On Fri, Dec 18, 2015 at 8:01 AM, Paolo Bonzini  wrote:

On 18/12/2015 16:19, Pavel Fedin wrote:

As far as i understand this code, KVM_EXIT_HYPERV is called when one
of three MSRs are accessed. But, shouldn't we have implemented
instead something more generic, like KVM_EXIT_REG_IO, which would
work similar to KVM_EXIT_PIO or KVM_EXIT_MMIO, but carry register
code and value?


Yes, we considered that.  There were actually patches for this as well.
  However, in this case the register is still emulated in the kernel, and
userspace just gets informed of the new value.


On brief inspection of Andrey's patch (I have not been following
closely) it looks like the kvm_hyperv_exit struct that's returned to
userspace contains more data (control, evt_page, and msg_page fields)
than simply the value of the MSR, so would the desired SynIC exit fit
into a general-purpose exit for MSR emulation?


Frankly I'm struggling trying to recall why we implemented it this way.
Actually all three fields are the values of respective MSRs and I don't
see any necessity to pass all three at the same time when any of them
gets updated.  The patch for QEMU adds an exit handler which processes
the fields individually, so I have a strong suspicion that union was
meant here rather than struct.

I hope Andrey will help to shed some light on that when he's back in the
office on Monday; meanwhile I think this peculiarity can be ignored.

Hello!

We have implemented Hyper-V related Vcpu exit not only for Hyper-V SynIC 
MSR's changes but also to provide future interface to transfer guest 
VMBus hypercalls parameters into QEMU.


Yes, we can use  KVM_EXIT_REG_IO/MSR_IO for Hyper-V SynIC MSRS's changes 
and can even use only one MSR value . So union inside struct 
kvm_hyperv_exit is excessive.


But we still need Vcpu exit to handle VMBus hypercalls by QEMU to 
emulate VMBus devices inside QEMU.


And currently we are going to extend struct kvm_hyperv_exit
to store Hyper-V VMBus hypercall parameters.

SynIC MSR's changes could be replaced by KVM_EXIT_REG_IO/MSR_IO
but could we replace Hyper-V VMBus hypercall and it's parameters
by KVM_EXIT_REG_IO/MSR_IO too?



Roman.





Re: [Qemu-devel] [PATCH v4 5/5] kvm/x86: Hyper-V kvm exit

2015-12-21 Thread Andrey Smetanin



On 12/21/2015 04:28 PM, Pavel Fedin wrote:

  Hello!


Yes, we can use  KVM_EXIT_REG_IO/MSR_IO for Hyper-V SynIC MSRS's changes
and can even use only one MSR value . So union inside struct
kvm_hyperv_exit is excessive.

But we still need Vcpu exit to handle VMBus hypercalls by QEMU to
emulate VMBus devices inside QEMU.

And currently we are going to extend struct kvm_hyperv_exit
to store Hyper-V VMBus hypercall parameters.


  Hm... Hypercalls, you say?
  We already have KVM_EXIT_HYPERCALL. Documentation says it's currently unused. 
Is it a leftover from ia64 KVM? Could we reuse it for
the purpose?


but could we replace Hyper-V VMBus hypercall and it's parameters
by KVM_EXIT_REG_IO/MSR_IO too?


  It depends. Can i read about these hypercalls somewhere? Is there any 
documentation?
I don't know about a documentation, but you can look at the code of 
Hyper-V hypercall handling inside KVM:


https://github.com/torvalds/linux/blob/master/arch/x86/kvm/hyperv.c#L346

The code simply decodes hypercall parameters from vcpu registers then 
handle hypercall code in switch and encode return code inside vcpu 
registers. Probably encode and decode of hypercall parameters/return 
code can be done in QEMU so we need only some exit with parameter that 
this is Hyper-V hypercall and probably KVM_EXIT_HYPERCALL is good for it.


But KVM_EXIT_HYPERCALL is not used inside KVM/QEMU so requires
implementation.



Kind regards,
Pavel Fedin
Expert Engineer
Samsung Electronics Research center Russia






[Qemu-devel] [PATCH v1 1/6] kvm/x86: Drop stimer_stop() function

2015-12-23 Thread Andrey Smetanin
The function stimer_stop() is called in one place
so remove the function and replace it's call by function
content.

Signed-off-by: Andrey Smetanin 
Reviewed-by: Roman Kagan 
CC: Gleb Natapov 
CC: Paolo Bonzini 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: qemu-devel@nongnu.org
---
 arch/x86/kvm/hyperv.c | 7 +--
 1 file changed, 1 insertion(+), 6 deletions(-)

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




[Qemu-devel] [PATCH v1 4/6] kvm/x86: Hyper-V fix SynIC timer disabling condition

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

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

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

Signed-off-by: Andrey Smetanin 
Reviewed-by: Roman Kagan 
CC: Gleb Natapov 
CC: Paolo Bonzini 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: qemu-devel@nongnu.org
---
 arch/x86/kvm/hyperv.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

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




[Qemu-devel] [PATCH v1 3/6] kvm/x86: Reorg stimer_expiration() to better control timer restart

2015-12-23 Thread Andrey Smetanin
Split stimer_expiration() into two parts - timer expiration message
sending and timer restart/cleanup based on timer state(config).

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

Signed-off-by: Andrey Smetanin 
Reviewed-by: Roman Kagan 
CC: Gleb Natapov 
CC: Paolo Bonzini 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: qemu-devel@nongnu.org
---
 arch/x86/kvm/hyperv.c | 26 ++
 1 file changed, 14 insertions(+), 12 deletions(-)

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




  1   2   >