diff --git a/xen/arch/x86/cpu-policy.c b/xen/arch/x86/cpu-policy.c index 5273fe0ae4..eddcd9778f 100644 --- a/xen/arch/x86/cpu-policy.c +++ b/xen/arch/x86/cpu-policy.c @@ -359,11 +359,18 @@ void calculate_raw_cpu_policy(void) /* Was already added by probe_cpuid_faulting() */ } -static void __init calculate_host_policy(void) +void __init calculate_host_cpu_policy(void) { struct cpu_policy *p = &host_cpu_policy; unsigned int max_extd_leaf; + /* + * Bail if the raw policy wasn't set up yet. At least recalculate_xstate() + * can't be used yet in that case. + */ + if ( !raw_cpu_policy.basic.max_leaf ) + return; + *p = raw_cpu_policy; p->basic.max_leaf = @@ -904,8 +911,6 @@ static void __init calculate_hvm_def_policy(void) void __init init_guest_cpu_policies(void) { - calculate_host_policy(); - if ( IS_ENABLED(CONFIG_PV) ) { calculate_pv_max_policy(); diff --git a/xen/arch/x86/cpu/common.c b/xen/arch/x86/cpu/common.c index fe8a818c1b..771ec2cf86 100644 --- a/xen/arch/x86/cpu/common.c +++ b/xen/arch/x86/cpu/common.c @@ -66,8 +66,10 @@ void __init setup_clear_cpu_cap(unsigned int cap) __clear_bit(cap, boot_cpu_data.x86_capability); dfs = x86_cpu_policy_lookup_deep_deps(cap); - if (!dfs) + if (!dfs) { + calculate_host_cpu_policy(); return; + } for (i = 0; i < FSCAPINTS; ++i) { cleared_caps[i] |= dfs[i]; @@ -78,6 +80,8 @@ void __init setup_clear_cpu_cap(unsigned int cap) __builtin_return_address(0), i, forced_caps[i] & dfs[i]); } + + calculate_host_cpu_policy(); } void __init setup_force_cpu_cap(unsigned int cap) @@ -92,6 +96,10 @@ void __init setup_force_cpu_cap(unsigned int cap) } __set_bit(cap, boot_cpu_data.x86_capability); + + /* Don't recalculate when the bit isn't represented in the policy. */ + if (cap < FSCAPINTS * 32) + calculate_host_cpu_policy(); } bool __init is_forced_cpu_cap(unsigned int cap) @@ -586,6 +594,8 @@ void identify_cpu(struct cpuinfo_x86 *c) } /* Now the feature flags better reflect actual CPU features! */ + if (c == &boot_cpu_data) + calculate_host_cpu_policy(); xstate_init(c); diff --git a/xen/arch/x86/include/asm/cpu-policy.h b/xen/arch/x86/include/asm/cpu-policy.h index 99d5a8e67e..943407963a 100644 --- a/xen/arch/x86/include/asm/cpu-policy.h +++ b/xen/arch/x86/include/asm/cpu-policy.h @@ -30,4 +30,10 @@ void recalculate_cpuid_policy(struct domain *d); */ void calculate_raw_cpu_policy(void); +/* + * Collect the host CPU policy. Called after collecting enough CPUID output, + * and again after all feature overrides have been put in place. + */ +void calculate_host_cpu_policy(void); + #endif /* X86_CPU_POLICY_H */