:p
atchew
Login
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(). Fixes: 894bd7617924 ("x86/Intel: use host CPU policy for ARAT checking") Reported-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com> Signed-off-by: Jan Beulich <jbeulich@suse.com> --- In the longer run we may need to (also) update the host policy from setup_{force,clear}_cpu_cap(). This really was part of one of the XSTATE cleanup patches at the head of the AMX series. This explains the specific placement ahead of the call to xstate_init()). Likely anything from there downwards shouldn't really live in identify_cpu() anyway. --- a/xen/arch/x86/cpu/common.c +++ b/xen/arch/x86/cpu/common.c @@ -XXX,XX +XXX,XX @@ void identify_cpu(struct cpuinfo_x86 *c) } /* Now the feature flags better reflect actual CPU features! */ + if (c == &boot_cpu_data) + calculate_host_policy(); xstate_init(c); --- a/xen/arch/x86/cpu-policy.c +++ b/xen/arch/x86/cpu-policy.c @@ -XXX,XX +XXX,XX @@ void calculate_raw_cpu_policy(void) /* Was already added by probe_cpuid_faulting() */ } -static void __init calculate_host_policy(void) +void __init calculate_host_policy(void) { struct cpu_policy *p = &host_cpu_policy; unsigned int max_extd_leaf; @@ -XXX,XX +XXX,XX @@ static void __init calculate_hvm_def_pol void __init init_guest_cpu_policies(void) { + /* Do this a 2nd time to account for setup_{clear,force}_cpu_cap() uses. */ calculate_host_policy(); if ( IS_ENABLED(CONFIG_PV) ) --- a/xen/arch/x86/include/asm/cpu-policy.h +++ b/xen/arch/x86/include/asm/cpu-policy.h @@ -XXX,XX +XXX,XX @@ void recalculate_cpuid_policy(struct dom */ 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_policy(void); + #endif /* X86_CPU_POLICY_H */
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 <marmarek@invisiblethingslab.com> Signed-off-by: Jan Beulich <jbeulich@suse.com> --- This really was part of one of the XSTATE cleanup patches at the head of the AMX series. This explains the specific placement ahead of the call to xstate_init()). Likely anything from there downwards shouldn't really live in identify_cpu() anyway. --- v2: Call calculate_host_cpu_policy() from setup_{force,clear}_cpu_cap() instead of from init_guest_cpu_policies(). --- a/xen/arch/x86/cpu/common.c +++ b/xen/arch/x86/cpu/common.c @@ -XXX,XX +XXX,XX @@ void __init setup_clear_cpu_cap(unsigned __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]; @@ -XXX,XX +XXX,XX @@ void __init setup_clear_cpu_cap(unsigned __builtin_return_address(0), i, forced_caps[i] & dfs[i]); } + + calculate_host_cpu_policy(); } void __init setup_force_cpu_cap(unsigned int cap) @@ -XXX,XX +XXX,XX @@ void __init setup_force_cpu_cap(unsigned } __set_bit(cap, boot_cpu_data.x86_capability); + + calculate_host_cpu_policy(); } bool __init is_forced_cpu_cap(unsigned int cap) @@ -XXX,XX +XXX,XX @@ 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); --- a/xen/arch/x86/cpu-policy.c +++ b/xen/arch/x86/cpu-policy.c @@ -XXX,XX +XXX,XX @@ 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 = @@ -XXX,XX +XXX,XX @@ static void __init calculate_hvm_def_pol void __init init_guest_cpu_policies(void) { - calculate_host_policy(); - if ( IS_ENABLED(CONFIG_PV) ) { calculate_pv_max_policy(); --- a/xen/arch/x86/include/asm/cpu-policy.h +++ b/xen/arch/x86/include/asm/cpu-policy.h @@ -XXX,XX +XXX,XX @@ void recalculate_cpuid_policy(struct dom */ 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 */