@@ -294,6 +294,173 @@ void update_guest_memory_policy(struct v
}
}
+void domain_cpu_policy_changed(struct domain *d)
+{
+ const struct cpuid_policy *p = d->arch.cpuid;
+ struct vcpu *v;
+
+ if ( is_pv_domain(d) )
+ {
+ if ( ((levelling_caps & LCAP_1cd) == LCAP_1cd) )
+ {
+ uint64_t mask = cpuidmask_defaults._1cd;
+ uint32_t ecx = p->basic._1c;
+ uint32_t edx = p->basic._1d;
+
+ /*
+ * Must expose hosts HTT and X2APIC value so a guest using native
+ * CPUID can correctly interpret other leaves which cannot be
+ * masked.
+ */
+ if ( cpu_has_x2apic )
+ ecx |= cpufeat_mask(X86_FEATURE_X2APIC);
+ if ( cpu_has_htt )
+ edx |= cpufeat_mask(X86_FEATURE_HTT);
+
+ switch ( boot_cpu_data.x86_vendor )
+ {
+ case X86_VENDOR_INTEL:
+ /*
+ * Intel masking MSRs are documented as AND masks.
+ * Experimentally, they are applied after OSXSAVE and APIC
+ * are fast-forwarded from real hardware state.
+ */
+ mask &= ((uint64_t)edx << 32) | ecx;
+
+ if ( ecx & cpufeat_mask(X86_FEATURE_XSAVE) )
+ ecx = cpufeat_mask(X86_FEATURE_OSXSAVE);
+ else
+ ecx = 0;
+ edx = cpufeat_mask(X86_FEATURE_APIC);
+
+ mask |= ((uint64_t)edx << 32) | ecx;
+ break;
+
+ case X86_VENDOR_AMD:
+ case X86_VENDOR_HYGON:
+ mask &= ((uint64_t)ecx << 32) | edx;
+
+ /*
+ * AMD masking MSRs are documented as overrides.
+ * Experimentally, fast-forwarding of the OSXSAVE and APIC
+ * bits from real hardware state only occurs if the MSR has
+ * the respective bits set.
+ */
+ if ( ecx & cpufeat_mask(X86_FEATURE_XSAVE) )
+ ecx = cpufeat_mask(X86_FEATURE_OSXSAVE);
+ else
+ ecx = 0;
+ edx = cpufeat_mask(X86_FEATURE_APIC);
+
+ /*
+ * If the Hypervisor bit is set in the policy, we can also
+ * forward it into real CPUID.
+ */
+ if ( p->basic.hypervisor )
+ ecx |= cpufeat_mask(X86_FEATURE_HYPERVISOR);
+
+ mask |= ((uint64_t)ecx << 32) | edx;
+ break;
+ }
+
+ d->arch.pv.cpuidmasks->_1cd = mask;
+ }
+
+ if ( ((levelling_caps & LCAP_6c) == LCAP_6c) )
+ {
+ uint64_t mask = cpuidmask_defaults._6c;
+
+ if ( boot_cpu_data.x86_vendor == X86_VENDOR_AMD )
+ mask &= (~0ULL << 32) | p->basic.raw[6].c;
+
+ d->arch.pv.cpuidmasks->_6c = mask;
+ }
+
+ if ( ((levelling_caps & LCAP_7ab0) == LCAP_7ab0) )
+ {
+ uint64_t mask = cpuidmask_defaults._7ab0;
+
+ /*
+ * Leaf 7[0].eax is max_subleaf, not a feature mask. Take it
+ * wholesale from the policy, but clamp the features in 7[0].ebx
+ * per usual.
+ */
+ if ( boot_cpu_data.x86_vendor &
+ (X86_VENDOR_AMD | X86_VENDOR_HYGON) )
+ mask = (((uint64_t)p->feat.max_subleaf << 32) |
+ ((uint32_t)mask & p->feat._7b0));
+
+ d->arch.pv.cpuidmasks->_7ab0 = mask;
+ }
+
+ if ( ((levelling_caps & LCAP_Da1) == LCAP_Da1) )
+ {
+ uint64_t mask = cpuidmask_defaults.Da1;
+ uint32_t eax = p->xstate.Da1;
+
+ if ( boot_cpu_data.x86_vendor == X86_VENDOR_INTEL )
+ mask &= (~0ULL << 32) | eax;
+
+ d->arch.pv.cpuidmasks->Da1 = mask;
+ }
+
+ if ( ((levelling_caps & LCAP_e1cd) == LCAP_e1cd) )
+ {
+ uint64_t mask = cpuidmask_defaults.e1cd;
+ uint32_t ecx = p->extd.e1c;
+ uint32_t edx = p->extd.e1d;
+
+ /*
+ * Must expose hosts CMP_LEGACY value so a guest using native
+ * CPUID can correctly interpret other leaves which cannot be
+ * masked.
+ */
+ if ( cpu_has_cmp_legacy )
+ ecx |= cpufeat_mask(X86_FEATURE_CMP_LEGACY);
+
+ /*
+ * If not emulating AMD or Hygon, clear the duplicated features
+ * in e1d.
+ */
+ if ( !(p->x86_vendor & (X86_VENDOR_AMD | X86_VENDOR_HYGON)) )
+ edx &= ~CPUID_COMMON_1D_FEATURES;
+
+ switch ( boot_cpu_data.x86_vendor )
+ {
+ case X86_VENDOR_INTEL:
+ mask &= ((uint64_t)edx << 32) | ecx;
+ break;
+
+ case X86_VENDOR_AMD:
+ case X86_VENDOR_HYGON:
+ mask &= ((uint64_t)ecx << 32) | edx;
+
+ /*
+ * Fast-forward bits - Must be set in the masking MSR for
+ * fast-forwarding to occur in hardware.
+ */
+ ecx = 0;
+ edx = cpufeat_mask(X86_FEATURE_APIC);
+
+ mask |= ((uint64_t)ecx << 32) | edx;
+ break;
+ }
+
+ d->arch.pv.cpuidmasks->e1cd = mask;
+ }
+ }
+
+ for_each_vcpu ( d, v )
+ {
+ cpuid_policy_updated(v);
+
+ /* If PMU version is zero then the guest doesn't have VPMU */
+ if ( boot_cpu_data.x86_vendor == X86_VENDOR_INTEL &&
+ p->basic.pmu_version == 0 )
+ vpmu_destroy(v);
+ }
+}
+
#ifndef CONFIG_BIGMEM
/*
* The hole may be at or above the 44-bit boundary, so we need to determine
@@ -49,173 +49,6 @@ static int gdbsx_guest_mem_io(domid_t do
}
#endif
-void domain_cpu_policy_changed(struct domain *d)
-{
- const struct cpuid_policy *p = d->arch.cpuid;
- struct vcpu *v;
-
- if ( is_pv_domain(d) )
- {
- if ( ((levelling_caps & LCAP_1cd) == LCAP_1cd) )
- {
- uint64_t mask = cpuidmask_defaults._1cd;
- uint32_t ecx = p->basic._1c;
- uint32_t edx = p->basic._1d;
-
- /*
- * Must expose hosts HTT and X2APIC value so a guest using native
- * CPUID can correctly interpret other leaves which cannot be
- * masked.
- */
- if ( cpu_has_x2apic )
- ecx |= cpufeat_mask(X86_FEATURE_X2APIC);
- if ( cpu_has_htt )
- edx |= cpufeat_mask(X86_FEATURE_HTT);
-
- switch ( boot_cpu_data.x86_vendor )
- {
- case X86_VENDOR_INTEL:
- /*
- * Intel masking MSRs are documented as AND masks.
- * Experimentally, they are applied after OSXSAVE and APIC
- * are fast-forwarded from real hardware state.
- */
- mask &= ((uint64_t)edx << 32) | ecx;
-
- if ( ecx & cpufeat_mask(X86_FEATURE_XSAVE) )
- ecx = cpufeat_mask(X86_FEATURE_OSXSAVE);
- else
- ecx = 0;
- edx = cpufeat_mask(X86_FEATURE_APIC);
-
- mask |= ((uint64_t)edx << 32) | ecx;
- break;
-
- case X86_VENDOR_AMD:
- case X86_VENDOR_HYGON:
- mask &= ((uint64_t)ecx << 32) | edx;
-
- /*
- * AMD masking MSRs are documented as overrides.
- * Experimentally, fast-forwarding of the OSXSAVE and APIC
- * bits from real hardware state only occurs if the MSR has
- * the respective bits set.
- */
- if ( ecx & cpufeat_mask(X86_FEATURE_XSAVE) )
- ecx = cpufeat_mask(X86_FEATURE_OSXSAVE);
- else
- ecx = 0;
- edx = cpufeat_mask(X86_FEATURE_APIC);
-
- /*
- * If the Hypervisor bit is set in the policy, we can also
- * forward it into real CPUID.
- */
- if ( p->basic.hypervisor )
- ecx |= cpufeat_mask(X86_FEATURE_HYPERVISOR);
-
- mask |= ((uint64_t)ecx << 32) | edx;
- break;
- }
-
- d->arch.pv.cpuidmasks->_1cd = mask;
- }
-
- if ( ((levelling_caps & LCAP_6c) == LCAP_6c) )
- {
- uint64_t mask = cpuidmask_defaults._6c;
-
- if ( boot_cpu_data.x86_vendor == X86_VENDOR_AMD )
- mask &= (~0ULL << 32) | p->basic.raw[6].c;
-
- d->arch.pv.cpuidmasks->_6c = mask;
- }
-
- if ( ((levelling_caps & LCAP_7ab0) == LCAP_7ab0) )
- {
- uint64_t mask = cpuidmask_defaults._7ab0;
-
- /*
- * Leaf 7[0].eax is max_subleaf, not a feature mask. Take it
- * wholesale from the policy, but clamp the features in 7[0].ebx
- * per usual.
- */
- if ( boot_cpu_data.x86_vendor &
- (X86_VENDOR_AMD | X86_VENDOR_HYGON) )
- mask = (((uint64_t)p->feat.max_subleaf << 32) |
- ((uint32_t)mask & p->feat._7b0));
-
- d->arch.pv.cpuidmasks->_7ab0 = mask;
- }
-
- if ( ((levelling_caps & LCAP_Da1) == LCAP_Da1) )
- {
- uint64_t mask = cpuidmask_defaults.Da1;
- uint32_t eax = p->xstate.Da1;
-
- if ( boot_cpu_data.x86_vendor == X86_VENDOR_INTEL )
- mask &= (~0ULL << 32) | eax;
-
- d->arch.pv.cpuidmasks->Da1 = mask;
- }
-
- if ( ((levelling_caps & LCAP_e1cd) == LCAP_e1cd) )
- {
- uint64_t mask = cpuidmask_defaults.e1cd;
- uint32_t ecx = p->extd.e1c;
- uint32_t edx = p->extd.e1d;
-
- /*
- * Must expose hosts CMP_LEGACY value so a guest using native
- * CPUID can correctly interpret other leaves which cannot be
- * masked.
- */
- if ( cpu_has_cmp_legacy )
- ecx |= cpufeat_mask(X86_FEATURE_CMP_LEGACY);
-
- /*
- * If not emulating AMD or Hygon, clear the duplicated features
- * in e1d.
- */
- if ( !(p->x86_vendor & (X86_VENDOR_AMD | X86_VENDOR_HYGON)) )
- edx &= ~CPUID_COMMON_1D_FEATURES;
-
- switch ( boot_cpu_data.x86_vendor )
- {
- case X86_VENDOR_INTEL:
- mask &= ((uint64_t)edx << 32) | ecx;
- break;
-
- case X86_VENDOR_AMD:
- case X86_VENDOR_HYGON:
- mask &= ((uint64_t)ecx << 32) | edx;
-
- /*
- * Fast-forward bits - Must be set in the masking MSR for
- * fast-forwarding to occur in hardware.
- */
- ecx = 0;
- edx = cpufeat_mask(X86_FEATURE_APIC);
-
- mask |= ((uint64_t)ecx << 32) | edx;
- break;
- }
-
- d->arch.pv.cpuidmasks->e1cd = mask;
- }
- }
-
- for_each_vcpu ( d, v )
- {
- cpuid_policy_updated(v);
-
- /* If PMU version is zero then the guest doesn't have VPMU */
- if ( boot_cpu_data.x86_vendor == X86_VENDOR_INTEL &&
- p->basic.pmu_version == 0 )
- vpmu_destroy(v);
- }
-}
-
static int update_domain_cpu_policy(struct domain *d,
xen_domctl_cpu_policy_t *xdpc)
{
This is in preparation of making the building of domctl.c conditional. Signed-off-by: Jan Beulich <jbeulich@suse.com>