diff --git a/docs/man/xl.cfg.5.pod.in b/docs/man/xl.cfg.5.pod.in index c8e017f950..3467eae2cd 100644 --- a/docs/man/xl.cfg.5.pod.in +++ b/docs/man/xl.cfg.5.pod.in @@ -2260,11 +2260,18 @@ mask. Hence this enlightenment must be specified for guests with more than 64 vCPUs if B and/or B are also specified. +=item B + +This group when set indicates to a guest that the hypervisor does not +explicitly have any limits on the number of Virtual processors a guest +is allowed to bring up. It is strongly recommended to keep this enabled +for guests with more than 64 vCPUs. + =item B This is a special value that enables the default set of groups, which is currently the B, B, B, B, -B and B groups. +B, B and B groups. =item B diff --git a/tools/include/libxl.h b/tools/include/libxl.h index 3488fbf56f..ee15c0495c 100644 --- a/tools/include/libxl.h +++ b/tools/include/libxl.h @@ -451,6 +451,12 @@ */ #define LIBXL_HAVE_VIRIDIAN_EX_PROCESSOR_MASKS 1 +/* + * LIBXL_HAVE_VIRIDIAN_NO_VP_LIMIT indicates that the 'no_vp_limit' value + * is present in the viridian enlightenment enumeration. + */ +#define LIBXL_HAVE_VIRIDIAN_NO_VP_LIMIT 1 + /* * LIBXL_HAVE_DEVICE_PCI_LIST_FREE indicates that the * libxl_device_pci_list_free() function is defined. diff --git a/tools/libs/light/libxl_types.idl b/tools/libs/light/libxl_types.idl index b4a9076b85..087a3db6e2 100644 --- a/tools/libs/light/libxl_types.idl +++ b/tools/libs/light/libxl_types.idl @@ -239,6 +239,7 @@ libxl_viridian_enlightenment = Enumeration("viridian_enlightenment", [ (8, "stimer"), (9, "hcall_ipi"), (10, "ex_processor_masks"), + (11, "no_vp_limit"), ]) libxl_hdtype = Enumeration("hdtype", [ diff --git a/tools/libs/light/libxl_x86.c b/tools/libs/light/libxl_x86.c index 86d272999d..5c4c194c65 100644 --- a/tools/libs/light/libxl_x86.c +++ b/tools/libs/light/libxl_x86.c @@ -309,6 +309,7 @@ static int hvm_set_viridian_features(libxl__gc *gc, uint32_t domid, libxl_bitmap_set(&enlightenments, LIBXL_VIRIDIAN_ENLIGHTENMENT_TIME_REF_COUNT); libxl_bitmap_set(&enlightenments, LIBXL_VIRIDIAN_ENLIGHTENMENT_APIC_ASSIST); libxl_bitmap_set(&enlightenments, LIBXL_VIRIDIAN_ENLIGHTENMENT_CRASH_CTL); + libxl_bitmap_set(&enlightenments, LIBXL_VIRIDIAN_ENLIGHTENMENT_NO_VP_LIMIT); } libxl_for_each_set_bit(v, info->u.hvm.viridian_enable) { @@ -369,6 +370,9 @@ static int hvm_set_viridian_features(libxl__gc *gc, uint32_t domid, if (libxl_bitmap_test(&enlightenments, LIBXL_VIRIDIAN_ENLIGHTENMENT_EX_PROCESSOR_MASKS)) mask |= HVMPV_ex_processor_masks; + if (libxl_bitmap_test(&enlightenments, LIBXL_VIRIDIAN_ENLIGHTENMENT_NO_VP_LIMIT)) + mask |= HVMPV_no_vp_limit; + if (mask != 0 && xc_hvm_param_set(CTX->xch, domid, diff --git a/xen/arch/x86/hvm/viridian/viridian.c b/xen/arch/x86/hvm/viridian/viridian.c index ed978047c1..ae1ea8630b 100644 --- a/xen/arch/x86/hvm/viridian/viridian.c +++ b/xen/arch/x86/hvm/viridian/viridian.c @@ -209,6 +209,29 @@ void cpuid_viridian_leaves(const struct vcpu *v, uint32_t leaf, res->b = viridian_spinlock_retry_count; break; + case 5: + /* + * From "Requirements for Implementing the Microsoft Hypervisor + * Interface": + * + * "On Windows operating systems versions through Windows Server + * 2008 R2, reporting the HV#1 hypervisor interface limits + * the Windows virtual machine to a maximum of 64 VPs, regardless of + * what is reported via CPUID.40000005.EAX. + * + * Starting with Windows Server 2012 and Windows 8, if + * CPUID.40000005.EAX containsa 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." + * + * For compatibility we hide it behind an option. + */ + if ( viridian_feature_mask(d) & HVMPV_no_vp_limit ) + res->a = -1; + break; + case 6: /* Detected and in use hardware features. */ if ( cpu_has_vmx_virtualize_apic_accesses ) diff --git a/xen/include/public/hvm/params.h b/xen/include/public/hvm/params.h index 3b0a0f45da..805f4ca44c 100644 --- a/xen/include/public/hvm/params.h +++ b/xen/include/public/hvm/params.h @@ -168,6 +168,10 @@ #define _HVMPV_ex_processor_masks 10 #define HVMPV_ex_processor_masks (1 << _HVMPV_ex_processor_masks) +/* Allow more than 64 VPs */ +#define _HVMPV_no_vp_limit 11 +#define HVMPV_no_vp_limit (1 << _HVMPV_no_vp_limit) + #define HVMPV_feature_mask \ (HVMPV_base_freq | \ HVMPV_no_freq | \ @@ -179,7 +183,8 @@ HVMPV_synic | \ HVMPV_stimer | \ HVMPV_hcall_ipi | \ - HVMPV_ex_processor_masks) + HVMPV_ex_processor_masks | \ + HVMPV_no_vp_limit) #endif