Message ID | 20240131230902.1867092-2-pbonzini@redhat.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | x86/cpu: fix invalid MTRR mask values for SEV or TME | expand |
On Thu, Feb 01, 2024 at 12:09:01AM +0100, Paolo Bonzini wrote: > In commit fbf6449f84bf ("x86/sev-es: Set x86_virt_bits to the correct > value straight away, instead of a two-phase approach"), the initialization > of c->x86_phys_bits was moved after this_cpu->c_early_init(c). This is > incorrect because early_init_amd() expected to be able to reduce the > value according to the contents of CPUID leaf 0x8000001f. > > Fortunately, the bug was negated by init_amd()'s call to early_init_amd(), > which does reduce x86_phys_bits in the end. However, this is very > late in the boot process and, most notably, the wrong value is used for > x86_phys_bits when setting up MTRRs. > > To fix this, call get_cpu_address_sizes() as soon as X86_FEATURE_CPUID is > set/cleared, and c->extended_cpuid_level is retrieved. > > Fixes: fbf6449f84bf ("x86/sev-es: Set x86_virt_bits to the correct value straight away, instead of a two-phase approach") > Cc: Adam Dunlap <acdunlap@google.com> > Cc: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> > Cc: Xiaoyao Li <xiaoyao.li@intel.com> > Cc: Kai Huang <kai.huang@intel.com> > Cc: Dave Hansen <dave.hansen@linux.intel.com> > Cc: Thomas Gleixner <tglx@linutronix.de> > Cc: Ingo Molnar <mingo@kernel.org> > Cc: x86@kernel.org > Cc: stable@vger.kernel.org > Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Reviewed-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
On 1/02/2024 7:09 am, Paolo Bonzini wrote: > In commit fbf6449f84bf ("x86/sev-es: Set x86_virt_bits to the correct > value straight away, instead of a two-phase approach"), the initialization > of c->x86_phys_bits was moved after this_cpu->c_early_init(c). This is > incorrect because early_init_amd() expected to be able to reduce the > value according to the contents of CPUID leaf 0x8000001f. > > Fortunately, the bug was negated by init_amd()'s call to early_init_amd(), > which does reduce x86_phys_bits in the end. However, this is very > late in the boot process and, most notably, the wrong value is used for > x86_phys_bits when setting up MTRRs. > > To fix this, call get_cpu_address_sizes() as soon as X86_FEATURE_CPUID is > set/cleared, and c->extended_cpuid_level is retrieved. > > Fixes: fbf6449f84bf ("x86/sev-es: Set x86_virt_bits to the correct value straight away, instead of a two-phase approach") > Cc: Adam Dunlap <acdunlap@google.com> > Cc: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> > Cc: Xiaoyao Li <xiaoyao.li@intel.com> > Cc: Kai Huang <kai.huang@intel.com> > Cc: Dave Hansen <dave.hansen@linux.intel.com> > Cc: Thomas Gleixner <tglx@linutronix.de> > Cc: Ingo Molnar <mingo@kernel.org> > Cc: x86@kernel.org > Cc: stable@vger.kernel.org > Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Acked-by: Kai Huang <kai.huang@intel.com>
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 0b97bcde70c6..fbc4e60d027c 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -1589,6 +1589,7 @@ static void __init early_identify_cpu(struct cpuinfo_x86 *c) get_cpu_vendor(c); get_cpu_cap(c); setup_force_cpu_cap(X86_FEATURE_CPUID); + get_cpu_address_sizes(c); cpu_parse_early_param(); if (this_cpu->c_early_init) @@ -1601,10 +1602,9 @@ static void __init early_identify_cpu(struct cpuinfo_x86 *c) this_cpu->c_bsp_init(c); } else { setup_clear_cpu_cap(X86_FEATURE_CPUID); + get_cpu_address_sizes(c); } - get_cpu_address_sizes(c); - setup_force_cpu_cap(X86_FEATURE_ALWAYS); cpu_set_bug_bits(c);
In commit fbf6449f84bf ("x86/sev-es: Set x86_virt_bits to the correct value straight away, instead of a two-phase approach"), the initialization of c->x86_phys_bits was moved after this_cpu->c_early_init(c). This is incorrect because early_init_amd() expected to be able to reduce the value according to the contents of CPUID leaf 0x8000001f. Fortunately, the bug was negated by init_amd()'s call to early_init_amd(), which does reduce x86_phys_bits in the end. However, this is very late in the boot process and, most notably, the wrong value is used for x86_phys_bits when setting up MTRRs. To fix this, call get_cpu_address_sizes() as soon as X86_FEATURE_CPUID is set/cleared, and c->extended_cpuid_level is retrieved. Fixes: fbf6449f84bf ("x86/sev-es: Set x86_virt_bits to the correct value straight away, instead of a two-phase approach") Cc: Adam Dunlap <acdunlap@google.com> Cc: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> Cc: Xiaoyao Li <xiaoyao.li@intel.com> Cc: Kai Huang <kai.huang@intel.com> Cc: Dave Hansen <dave.hansen@linux.intel.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Ingo Molnar <mingo@kernel.org> Cc: x86@kernel.org Cc: stable@vger.kernel.org Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- arch/x86/kernel/cpu/common.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)