[Qemu-devel] [PATCH] i386/kvm: add support for Hyper-V TLB flush

Vitaly Kuznetsov posted 1 patch 5 years, 10 months ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20180610184927.19309-1-vkuznets@redhat.com
Test checkpatch passed
Test docker-mingw@fedora passed
Test docker-quick@centos7 passed
Test s390x passed
linux-headers/linux/kvm.h  |  1 +
target/i386/cpu.c          |  1 +
target/i386/cpu.h          |  1 +
target/i386/hyperv-proto.h |  1 +
target/i386/kvm.c          | 15 ++++++++++++++-
5 files changed, 18 insertions(+), 1 deletion(-)
[Qemu-devel] [PATCH] i386/kvm: add support for Hyper-V TLB flush
Posted by Vitaly Kuznetsov 5 years, 10 months ago
Add support for Hyper-V TLB flush which recently got added to KVM.

Just like regular Hyper-V we announce HV_EX_PROCESSOR_MASKS_RECOMMENDED
regardless of how many vCPUs we have. Windows is 'smart' and uses less
expensive non-EX Hypercall whenever possible (when it wants to flush TLB
for all vCPUs or the maximum vCPU index in the vCPU set requires flushing
is less than 64).

Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
---
 linux-headers/linux/kvm.h  |  1 +
 target/i386/cpu.c          |  1 +
 target/i386/cpu.h          |  1 +
 target/i386/hyperv-proto.h |  1 +
 target/i386/kvm.c          | 15 ++++++++++++++-
 5 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
index cdb148e959..a52a685690 100644
--- a/linux-headers/linux/kvm.h
+++ b/linux-headers/linux/kvm.h
@@ -948,6 +948,7 @@ struct kvm_ppc_resize_hpt {
 #define KVM_CAP_S390_BPB 152
 #define KVM_CAP_GET_MSR_FEATURES 153
 #define KVM_CAP_HYPERV_EVENTFD 154
+#define KVM_CAP_HYPERV_TLBFLUSH 155
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 94260412e2..756cc78808 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -5151,6 +5151,7 @@ static Property x86_cpu_properties[] = {
     DEFINE_PROP_BOOL("hv-stimer", X86CPU, hyperv_stimer, false),
     DEFINE_PROP_BOOL("hv-frequencies", X86CPU, hyperv_frequencies, false),
     DEFINE_PROP_BOOL("hv-reenlightenment", X86CPU, hyperv_reenlightenment, false),
+    DEFINE_PROP_BOOL("hv-tlbflush", X86CPU, hyperv_tlbflush, 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 664504610e..738d695331 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -1363,6 +1363,7 @@ struct X86CPU {
     bool hyperv_stimer;
     bool hyperv_frequencies;
     bool hyperv_reenlightenment;
+    bool hyperv_tlbflush;
     bool check_cpuid;
     bool enforce_cpuid;
     bool expose_kvm;
diff --git a/target/i386/hyperv-proto.h b/target/i386/hyperv-proto.h
index 93352ebd2a..d6d5a79293 100644
--- a/target/i386/hyperv-proto.h
+++ b/target/i386/hyperv-proto.h
@@ -58,6 +58,7 @@
 #define HV_APIC_ACCESS_RECOMMENDED          (1u << 3)
 #define HV_SYSTEM_RESET_RECOMMENDED         (1u << 4)
 #define HV_RELAXED_TIMING_RECOMMENDED       (1u << 5)
+#define HV_EX_PROCESSOR_MASKS_RECOMMENDED   (1u << 11)
 
 /*
  * Basic virtualized MSRs
diff --git a/target/i386/kvm.c b/target/i386/kvm.c
index 44f70733e7..91c8e952c8 100644
--- a/target/i386/kvm.c
+++ b/target/i386/kvm.c
@@ -585,7 +585,8 @@ static bool hyperv_enabled(X86CPU *cpu)
             cpu->hyperv_runtime ||
             cpu->hyperv_synic ||
             cpu->hyperv_stimer ||
-            cpu->hyperv_reenlightenment);
+            cpu->hyperv_reenlightenment ||
+            cpu->hyperv_tlbflush);
 }
 
 static int kvm_arch_set_tsc_khz(CPUState *cs)
@@ -823,6 +824,18 @@ int kvm_arch_init_vcpu(CPUState *cs)
         if (cpu->hyperv_vapic) {
             c->eax |= HV_APIC_ACCESS_RECOMMENDED;
         }
+        if (cpu->hyperv_tlbflush) {
+            if (kvm_check_extension(cs->kvm_state,
+                                    KVM_CAP_HYPERV_TLBFLUSH) <= 0) {
+                fprintf(stderr, "Hyper-V TLB flush support "
+                        "(requested by 'hv-tlbflush' cpu flag) "
+                        " is not supported by kernel\n");
+                return -ENOSYS;
+            }
+            c->eax |= HV_REMOTE_TLB_FLUSH_RECOMMENDED;
+            c->eax |= HV_EX_PROCESSOR_MASKS_RECOMMENDED;
+        }
+
         c->ebx = cpu->hyperv_spinlock_attempts;
 
         c = &cpuid_data.entries[cpuid_i++];
-- 
2.14.4


Re: [Qemu-devel] [PATCH] i386/kvm: add support for Hyper-V TLB flush
Posted by Roman Kagan 5 years, 10 months ago
On Sun, Jun 10, 2018 at 08:49:27PM +0200, Vitaly Kuznetsov wrote:
> Add support for Hyper-V TLB flush which recently got added to KVM.
> 
> Just like regular Hyper-V we announce HV_EX_PROCESSOR_MASKS_RECOMMENDED
> regardless of how many vCPUs we have. Windows is 'smart' and uses less
> expensive non-EX Hypercall whenever possible (when it wants to flush TLB
> for all vCPUs or the maximum vCPU index in the vCPU set requires flushing
> is less than 64).

Indeed, reading the spec it sounds like this bit indicates the
availability of hypercalls accepting sparse processor sets, rather than
the recommendation to use them (dunno if we want to ajust the name).

> Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
> ---
>  linux-headers/linux/kvm.h  |  1 +
>  target/i386/cpu.c          |  1 +
>  target/i386/cpu.h          |  1 +
>  target/i386/hyperv-proto.h |  1 +
>  target/i386/kvm.c          | 15 ++++++++++++++-
>  5 files changed, 18 insertions(+), 1 deletion(-)
> 
> diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
> index cdb148e959..a52a685690 100644
> --- a/linux-headers/linux/kvm.h
> +++ b/linux-headers/linux/kvm.h
> @@ -948,6 +948,7 @@ struct kvm_ppc_resize_hpt {
>  #define KVM_CAP_S390_BPB 152
>  #define KVM_CAP_GET_MSR_FEATURES 153
>  #define KVM_CAP_HYPERV_EVENTFD 154
> +#define KVM_CAP_HYPERV_TLBFLUSH 155
>  
>  #ifdef KVM_CAP_IRQ_ROUTING
>  

This header is imported from the kernel, so, to make life easier for the
maintainers, I tend to post changes to it in a separate patch,
indicating which kernel version contains it (AFAIK it's in kvm/queue
ATM).  But if they actually do want it they'll let you know ;)

Reviewed-by: Roman Kagan <rkagan@virtuozzo.com>

Re: [Qemu-devel] [PATCH] i386/kvm: add support for Hyper-V TLB flush
Posted by Vitaly Kuznetsov 5 years, 10 months ago
Vitaly Kuznetsov <vkuznets@redhat.com> writes:

> Add support for Hyper-V TLB flush which recently got added to KVM.
>
> Just like regular Hyper-V we announce HV_EX_PROCESSOR_MASKS_RECOMMENDED
> regardless of how many vCPUs we have. Windows is 'smart' and uses less
> expensive non-EX Hypercall whenever possible (when it wants to flush TLB
> for all vCPUs or the maximum vCPU index in the vCPU set requires flushing
> is less than 64).
>

Ping?

-- 
  Vitaly

Re: [Qemu-devel] [PATCH] i386/kvm: add support for Hyper-V TLB flush
Posted by Paolo Bonzini 5 years, 10 months ago
On 10/06/2018 20:49, Vitaly Kuznetsov wrote:
> Add support for Hyper-V TLB flush which recently got added to KVM.
> 
> Just like regular Hyper-V we announce HV_EX_PROCESSOR_MASKS_RECOMMENDED
> regardless of how many vCPUs we have. Windows is 'smart' and uses less
> expensive non-EX Hypercall whenever possible (when it wants to flush TLB
> for all vCPUs or the maximum vCPU index in the vCPU set requires flushing
> is less than 64).
> 
> Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
> ---
>  linux-headers/linux/kvm.h  |  1 +
>  target/i386/cpu.c          |  1 +
>  target/i386/cpu.h          |  1 +
>  target/i386/hyperv-proto.h |  1 +
>  target/i386/kvm.c          | 15 ++++++++++++++-
>  5 files changed, 18 insertions(+), 1 deletion(-)
> 
> diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
> index cdb148e959..a52a685690 100644
> --- a/linux-headers/linux/kvm.h
> +++ b/linux-headers/linux/kvm.h
> @@ -948,6 +948,7 @@ struct kvm_ppc_resize_hpt {
>  #define KVM_CAP_S390_BPB 152
>  #define KVM_CAP_GET_MSR_FEATURES 153
>  #define KVM_CAP_HYPERV_EVENTFD 154
> +#define KVM_CAP_HYPERV_TLBFLUSH 155
>  
>  #ifdef KVM_CAP_IRQ_ROUTING
>  
> diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> index 94260412e2..756cc78808 100644
> --- a/target/i386/cpu.c
> +++ b/target/i386/cpu.c
> @@ -5151,6 +5151,7 @@ static Property x86_cpu_properties[] = {
>      DEFINE_PROP_BOOL("hv-stimer", X86CPU, hyperv_stimer, false),
>      DEFINE_PROP_BOOL("hv-frequencies", X86CPU, hyperv_frequencies, false),
>      DEFINE_PROP_BOOL("hv-reenlightenment", X86CPU, hyperv_reenlightenment, false),
> +    DEFINE_PROP_BOOL("hv-tlbflush", X86CPU, hyperv_tlbflush, 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 664504610e..738d695331 100644
> --- a/target/i386/cpu.h
> +++ b/target/i386/cpu.h
> @@ -1363,6 +1363,7 @@ struct X86CPU {
>      bool hyperv_stimer;
>      bool hyperv_frequencies;
>      bool hyperv_reenlightenment;
> +    bool hyperv_tlbflush;
>      bool check_cpuid;
>      bool enforce_cpuid;
>      bool expose_kvm;
> diff --git a/target/i386/hyperv-proto.h b/target/i386/hyperv-proto.h
> index 93352ebd2a..d6d5a79293 100644
> --- a/target/i386/hyperv-proto.h
> +++ b/target/i386/hyperv-proto.h
> @@ -58,6 +58,7 @@
>  #define HV_APIC_ACCESS_RECOMMENDED          (1u << 3)
>  #define HV_SYSTEM_RESET_RECOMMENDED         (1u << 4)
>  #define HV_RELAXED_TIMING_RECOMMENDED       (1u << 5)
> +#define HV_EX_PROCESSOR_MASKS_RECOMMENDED   (1u << 11)
>  
>  /*
>   * Basic virtualized MSRs
> diff --git a/target/i386/kvm.c b/target/i386/kvm.c
> index 44f70733e7..91c8e952c8 100644
> --- a/target/i386/kvm.c
> +++ b/target/i386/kvm.c
> @@ -585,7 +585,8 @@ static bool hyperv_enabled(X86CPU *cpu)
>              cpu->hyperv_runtime ||
>              cpu->hyperv_synic ||
>              cpu->hyperv_stimer ||
> -            cpu->hyperv_reenlightenment);
> +            cpu->hyperv_reenlightenment ||
> +            cpu->hyperv_tlbflush);
>  }
>  
>  static int kvm_arch_set_tsc_khz(CPUState *cs)
> @@ -823,6 +824,18 @@ int kvm_arch_init_vcpu(CPUState *cs)
>          if (cpu->hyperv_vapic) {
>              c->eax |= HV_APIC_ACCESS_RECOMMENDED;
>          }
> +        if (cpu->hyperv_tlbflush) {
> +            if (kvm_check_extension(cs->kvm_state,
> +                                    KVM_CAP_HYPERV_TLBFLUSH) <= 0) {
> +                fprintf(stderr, "Hyper-V TLB flush support "
> +                        "(requested by 'hv-tlbflush' cpu flag) "
> +                        " is not supported by kernel\n");
> +                return -ENOSYS;
> +            }
> +            c->eax |= HV_REMOTE_TLB_FLUSH_RECOMMENDED;
> +            c->eax |= HV_EX_PROCESSOR_MASKS_RECOMMENDED;
> +        }
> +
>          c->ebx = cpu->hyperv_spinlock_attempts;
>  
>          c = &cpuid_data.entries[cpuid_i++];
> 

Queued, thanks.

Paolo