From aa2f6c99f3b7d2babbe21cdf81a6e5656583e242 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Wed, 29 Jul 2026 16:02:31 +0200 Subject: [PATCH] x86/cpu-policy: set up host policy earlier MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In order to use cpu_has_* expanding to host_cpu_policy.*, the host policy needs setting up alongside boot_cpu_data.x86_capability[]. Arrange for that towards the end of identify_cpu(). Then make sure .x86_capability[] and host policy remain in sync when setup_{force,clear}_cpu_cap() are used. Rename the function now it's no longer static. Fixes: 894bd7617924 ("x86/Intel: use host CPU policy for ARAT checking") Reported-by: Marek Marczykowski-Górecki Signed-off-by: Jan Beulich Acked-by: Andrew Cooper Release-Acked-by: Oleksii Kurochko --- xen/arch/x86/cpu-policy.c | 11 ++++++++--- xen/arch/x86/cpu/common.c | 12 +++++++++++- xen/arch/x86/include/asm/cpu-policy.h | 6 ++++++ 3 files changed, 25 insertions(+), 4 deletions(-) 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 */