Blob Blame History Raw
From b2f9f4fcaad9c64f4551ab1dbe9e474c3dc6b2b4 Mon Sep 17 00:00:00 2001
From: Miroslav Rezanina <mrezanin@redhat.com>
Date: Mon, 27 Nov 2017 12:59:13 +0100
Subject: [PATCH 10/15] i386/cpu/hyperv: support over 64 vcpus for windows
 guests

RH-Author: vrozenfe <vrozenfe@redhat.com>
Message-id: <1511256034-28105-1-git-send-email-vrozenfe@redhat.com>
Patchwork-id: 77769
O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH v2] i386/cpu/hyperv: support over 64 vcpus for windows guests
Bugzilla: 1451959
RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>

From: Gonglei <arei.gonglei@huawei.com>

Upstream-status: 6c69dfb67e84747cf071958594d939e845dfcc0c

Starting with Windows Server 2012 and Windows 8, if
CPUID.40000005.EAX contains a value of -1, Windows assumes specific
limit to the number of VPs. In this case, Windows Server 2012
guest VMs may use more than 64 VPs, up to the maximum supported
number of processors applicable to the specific Windows
version being used.

https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/reference/tlfs

For compatibility, Let's introduce a new property for X86CPU,
named "x-hv-max-vps" as Eduardo's suggestion, and set it
to 0x40 before machine 2.10.

(The "x-" prefix indicates that the property is not supposed to
be a stable user interface.)

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Message-Id: <1505143227-14324-1-git-send-email-arei.gonglei@huawei.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Vadim Rozenfeld <vrozenfe@redhat.com>
---
 include/hw/i386/pc.h |  5 +++++
 target/i386/cpu.c    | 13 +++++++++++++
 target/i386/cpu.h    |  2 ++
 target/i386/kvm.c    |  3 ++-
 4 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 7b46121..f9b7998 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -1089,6 +1089,11 @@ extern void igd_passthrough_isa_bridge_create(PCIBus *bus, uint16_t gpu_dev_id);
             .driver = TYPE_X86_CPU,\
             .property = "kvm-no-smi-migration",\
             .value    = "on",\
+        },\
+        { /* PC_RHEL7_4_COMPAT from PC_COMPAT_2_10 */ \
+             .driver   = TYPE_X86_CPU,\
+             .property = "x-hv-max-vps",\
+             .value    = "0x40",\
         },
 
 #define PC_RHEL7_2_COMPAT \
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index ca95336..c2dee60 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -4179,6 +4179,19 @@ static Property x86_cpu_properties[] = {
                      false),
     DEFINE_PROP_BOOL("vmware-cpuid-freq", X86CPU, vmware_cpuid_freq, true),
     DEFINE_PROP_BOOL("tcg-cpuid", X86CPU, expose_tcg, true),
+    /*
+     * From "Requirements for Implementing the Microsoft
+     * Hypervisor Interface":
+     * https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/reference/tlfs
+     *
+     * "Starting with Windows Server 2012 and Windows 8, if
+     * CPUID.40000005.EAX contains a value of -1, Windows assumes that
+     * the hypervisor imposes no specific limit to the number of VPs.
+     * In this case, Windows Server 2012 guest VMs may use more than
+     * 64 VPs, up to the maximum supported number of processors applicable
+     * to the specific Windows version being used."
+     */
+    DEFINE_PROP_INT32("x-hv-max-vps", X86CPU, hv_max_vps, -1),
     DEFINE_PROP_END_OF_LIST()
 };
 
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 0518673..fd73888 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -1282,6 +1282,8 @@ struct X86CPU {
     int32_t socket_id;
     int32_t core_id;
     int32_t thread_id;
+
+    int32_t hv_max_vps;
 };
 
 static inline X86CPU *x86_env_get_cpu(CPUX86State *env)
diff --git a/target/i386/kvm.c b/target/i386/kvm.c
index 739334a..ee4e91f 100644
--- a/target/i386/kvm.c
+++ b/target/i386/kvm.c
@@ -786,7 +786,8 @@ int kvm_arch_init_vcpu(CPUState *cs)
 
         c = &cpuid_data.entries[cpuid_i++];
         c->function = HYPERV_CPUID_IMPLEMENT_LIMITS;
-        c->eax = 0x40;
+
+        c->eax = cpu->hv_max_vps;
         c->ebx = 0x40;
 
         kvm_base = KVM_CPUID_SIGNATURE_NEXT;
-- 
1.8.3.1