On Mon, Dec 06, 2021 at 05:09:42PM +0100, Jan Beulich wrote: > On 29.11.2021 16:33, Roger Pau Monne wrote: > > @@ -458,22 +456,6 @@ int xc_cpuid_apply_policy(xc_interface *xch, uint32_t > > domid, bool restore, > > (p = calloc(1, sizeof(*p))) == NULL ) > > goto out; > > > > - /* Get the host policy. */ > > - rc = xc_get_cpu_featureset(xch, XEN_SYSCTL_cpu_featureset_host, > > - &len, host_featureset); > > You go from retrieving the host featureset to ... > > > @@ -944,3 +865,98 @@ int xc_cpu_policy_make_compat_4_12(xc_interface *xch, > > xc_cpu_policy_t *policy, > > xc_cpu_policy_destroy(host); > > return rc; > > } > > + > > +int xc_cpu_policy_legacy_topology(xc_interface *xch, xc_cpu_policy_t > > *policy, > > + bool hvm) > > +{ > > + if ( !hvm ) > > + { > > + xc_cpu_policy_t *host; > > + int rc; > > + > > + host = xc_cpu_policy_init(); > > + if ( !host ) > > + { > > + errno = ENOMEM; > > + return -1; > > + } > > + > > + rc = xc_cpu_policy_get_system(xch, XEN_SYSCTL_cpu_policy_host, > > host); > > ... retrieving the host policy, which afaict is a larger blob of data. > Is there a particular reason for doing so?
I did that so I could assign from one CPUID policy to another, but will revert back to using a featureset since it's indeed smaller. > > + if ( rc ) > > + { > > + ERROR("Failed to get host policy"); > > + xc_cpu_policy_destroy(host); > > + return rc; > > + } > > + > > + > > + /* > > + * On hardware without CPUID Faulting, PV guests see real topology. > > + * As a consequence, they also need to see the host htt/cmp fields. > > + */ > > + policy->cpuid.basic.htt = host->cpuid.basic.htt; > > + policy->cpuid.extd.cmp_legacy = host->cpuid.extd.cmp_legacy; > > + } > > + else > > + { > > + unsigned int i; > > + > > + /* > > + * Topology for HVM guests is entirely controlled by Xen. For > > now, we > > + * hardcode APIC_ID = vcpu_id * 2 to give the illusion of no SMT. > > + */ > > + policy->cpuid.basic.htt = true; > > + policy->cpuid.extd.cmp_legacy = false; > > + > > + /* > > + * Leaf 1 EBX[23:16] is Maximum Logical Processors Per Package. > > + * Update to reflect vLAPIC_ID = vCPU_ID * 2, but make sure to > > avoid > > + * overflow. > > + */ > > + if ( !policy->cpuid.basic.lppp ) > > + policy->cpuid.basic.lppp = 2; > > + else if ( !(policy->cpuid.basic.lppp & 0x80) ) > > + policy->cpuid.basic.lppp *= 2; > > + > > + switch ( policy->cpuid.x86_vendor ) > > + { > > + case X86_VENDOR_INTEL: > > + for ( i = 0; (policy->cpuid.cache.subleaf[i].type && > > + i < ARRAY_SIZE(policy->cpuid.cache.raw)); ++i ) > > + { > > + policy->cpuid.cache.subleaf[i].cores_per_package = > > + (policy->cpuid.cache.subleaf[i].cores_per_package << 1) > > | 1; > > + policy->cpuid.cache.subleaf[i].threads_per_cache = 0; > > + } > > + break; > > + > > + case X86_VENDOR_AMD: > > + case X86_VENDOR_HYGON: > > + /* > > + * Leaf 0x80000008 ECX[15:12] is ApicIdCoreSize. > > + * Leaf 0x80000008 ECX[7:0] is NumberOfCores (minus one). > > + * Update to reflect vLAPIC_ID = vCPU_ID * 2. But avoid > > + * - overflow, > > + * - going out of sync with leaf 1 EBX[23:16], > > + * - incrementing ApicIdCoreSize when it's zero (which changes > > the > > + * meaning of bits 7:0). > > + * > > + * UPDATE: I addition to avoiding overflow, some > > Nit: Would you mind switching "I" to "In" at this occasion? Will do. Thanks, Roger.