Commit 067d66ba authored by Andi Kleen's avatar Andi Kleen Committed by Chris Wright

[PATCH] x86_64/i386: Compute correct MTRR mask on early Noconas

Force correct address space size for MTRR on some 64bit Intel Xeons

They report 40bit, but only have 36bits of physical address space.
This caused problems with setting up the correct masks for MTRR,
resulting in incorrect MTRRs.

CPUID workaround for steppings 0F33h(supporting x86) and 0F34h(supporting x86
and EM64T). Detail info can be found at:
http://download.intel.com/design/Xeon/specupdt/30240216.pdf
http://download.intel.com/design/Pentium4/specupdt/30235221.pdf

Signed-off-by: Shaohua Li<shaohua.li@intel.com>
Signed-off-by: default avatarAndi Kleen <ak@suse.de>
Signed-off-by: default avatarChris Wright <chrisw@osdl.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 4b490b0c
...@@ -626,6 +626,14 @@ void __init mtrr_bp_init(void) ...@@ -626,6 +626,14 @@ void __init mtrr_bp_init(void)
if (cpuid_eax(0x80000000) >= 0x80000008) { if (cpuid_eax(0x80000000) >= 0x80000008) {
u32 phys_addr; u32 phys_addr;
phys_addr = cpuid_eax(0x80000008) & 0xff; phys_addr = cpuid_eax(0x80000008) & 0xff;
/* CPUID workaround for Intel 0F33/0F34 CPU */
if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL &&
boot_cpu_data.x86 == 0xF &&
boot_cpu_data.x86_model == 0x3 &&
(boot_cpu_data.x86_mask == 0x3 ||
boot_cpu_data.x86_mask == 0x4))
phys_addr = 36;
size_or_mask = ~((1 << (phys_addr - PAGE_SHIFT)) - 1); size_or_mask = ~((1 << (phys_addr - PAGE_SHIFT)) - 1);
size_and_mask = ~size_or_mask & 0xfff00000; size_and_mask = ~size_or_mask & 0xfff00000;
} else if (boot_cpu_data.x86_vendor == X86_VENDOR_CENTAUR && } else if (boot_cpu_data.x86_vendor == X86_VENDOR_CENTAUR &&
......
...@@ -993,6 +993,11 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c) ...@@ -993,6 +993,11 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c)
unsigned eax = cpuid_eax(0x80000008); unsigned eax = cpuid_eax(0x80000008);
c->x86_virt_bits = (eax >> 8) & 0xff; c->x86_virt_bits = (eax >> 8) & 0xff;
c->x86_phys_bits = eax & 0xff; c->x86_phys_bits = eax & 0xff;
/* CPUID workaround for Intel 0F34 CPU */
if (c->x86_vendor == X86_VENDOR_INTEL &&
c->x86 == 0xF && c->x86_model == 0x3 &&
c->x86_mask == 0x4)
c->x86_phys_bits = 36;
} }
if (c->x86 == 15) if (c->x86 == 15)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment