|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH for 4.19?] x86/Intel: unlock CPUID earlier for the BSP
On Thu, Jun 13, 2024 at 10:19:30AM +0200, Jan Beulich wrote:
> Intel CPUs have a MSR bit to limit CPUID enumeration to leaf two. If
> this bit is set by the BIOS then CPUID evaluation does not work when
> data from any leaf greater than two is needed; early_cpu_init() in
> particular wants to collect leaf 7 data.
>
> Cure this by unlocking CPUID right before evaluating anything which
> depends on the maximum CPUID leaf being greater than two.
>
> Inspired by (and description cloned from) Linux commit 0c2f6d04619e
> ("x86/topology/intel: Unlock CPUID before evaluating anything").
>
> Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
> ---
> While I couldn't spot anything, it kind of feels as if I'm overlooking
> further places where we might be inspecting in particular leaf 7 yet
> earlier.
>
> No Fixes: tag(s), as imo it would be too many that would want
> enumerating.
>
> --- a/xen/arch/x86/cpu/common.c
> +++ b/xen/arch/x86/cpu/common.c
> @@ -336,7 +336,8 @@ void __init early_cpu_init(bool verbose)
>
> c->x86_vendor = x86_cpuid_lookup_vendor(ebx, ecx, edx);
> switch (c->x86_vendor) {
> - case X86_VENDOR_INTEL: actual_cpu = intel_cpu_dev; break;
> + case X86_VENDOR_INTEL: intel_unlock_cpuid_leaves(c);
> + actual_cpu = intel_cpu_dev; break;
> case X86_VENDOR_AMD: actual_cpu = amd_cpu_dev; break;
> case X86_VENDOR_CENTAUR: actual_cpu = centaur_cpu_dev; break;
> case X86_VENDOR_SHANGHAI: actual_cpu = shanghai_cpu_dev; break;
> --- a/xen/arch/x86/cpu/cpu.h
> +++ b/xen/arch/x86/cpu/cpu.h
> @@ -24,3 +24,5 @@ void amd_init_lfence(struct cpuinfo_x86
> void amd_init_ssbd(const struct cpuinfo_x86 *c);
> void amd_init_spectral_chicken(void);
> void detect_zen2_null_seg_behaviour(void);
> +
> +void intel_unlock_cpuid_leaves(struct cpuinfo_x86 *c);
> --- a/xen/arch/x86/cpu/intel.c
> +++ b/xen/arch/x86/cpu/intel.c
> @@ -303,10 +303,24 @@ static void __init noinline intel_init_l
> ctxt_switch_masking = intel_ctxt_switch_masking;
> }
>
> -static void cf_check early_init_intel(struct cpuinfo_x86 *c)
> +/* Unmask CPUID levels if masked. */
> +void intel_unlock_cpuid_leaves(struct cpuinfo_x86 *c)
> {
> - u64 misc_enable, disable;
> + uint64_t misc_enable, disable;
> +
> + rdmsrl(MSR_IA32_MISC_ENABLE, misc_enable);
> +
> + disable = misc_enable & MSR_IA32_MISC_ENABLE_LIMIT_CPUID;
> + if (disable) {
> + wrmsrl(MSR_IA32_MISC_ENABLE, misc_enable & ~disable);
> + bootsym(trampoline_misc_enable_off) |= disable;
> + c->cpuid_level = cpuid_eax(0);
> + printk(KERN_INFO "revised cpuid level: %u\n", c->cpuid_level);
> + }
> +}
>
> +static void cf_check early_init_intel(struct cpuinfo_x86 *c)
> +{
> /* Netburst reports 64 bytes clflush size, but does IO in 128 bytes */
> if (c->x86 == 15 && c->x86_cache_alignment == 64)
> c->x86_cache_alignment = 128;
> @@ -315,16 +329,7 @@ static void cf_check early_init_intel(st
> bootsym(trampoline_misc_enable_off) &
> MSR_IA32_MISC_ENABLE_XD_DISABLE)
> printk(KERN_INFO "re-enabled NX (Execute Disable)
> protection\n");
>
> - /* Unmask CPUID levels and NX if masked: */
> - rdmsrl(MSR_IA32_MISC_ENABLE, misc_enable);
> -
> - disable = misc_enable & MSR_IA32_MISC_ENABLE_LIMIT_CPUID;
> - if (disable) {
> - wrmsrl(MSR_IA32_MISC_ENABLE, misc_enable & ~disable);
> - bootsym(trampoline_misc_enable_off) |= disable;
> - printk(KERN_INFO "revised cpuid level: %d\n",
> - cpuid_eax(0));
> - }
> + intel_unlock_cpuid_leaves(c);
Do you really need to call intel_unlock_cpuid_leaves() here?
For the BSP it will be taken care in early_cpu_init(), and for the APs
MSR_IA32_MISC_ENABLE it will be set as part of the trampoline with the
disables from trampoline_misc_enable_off.
Thanks, Roger.
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |