Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[PATCH] x86_64: 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.

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: Andi Kleen <ak@suse.de>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by

Shaohua Li and committed by
Linus Torvalds
af9c142d 1d2e6bd8

+13
+8
arch/i386/kernel/cpu/mtrr/main.c
··· 626 626 if (cpuid_eax(0x80000000) >= 0x80000008) { 627 627 u32 phys_addr; 628 628 phys_addr = cpuid_eax(0x80000008) & 0xff; 629 + /* CPUID workaround for Intel 0F33/0F34 CPU */ 630 + if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && 631 + boot_cpu_data.x86 == 0xF && 632 + boot_cpu_data.x86_model == 0x3 && 633 + (boot_cpu_data.x86_mask == 0x3 || 634 + boot_cpu_data.x86_mask == 0x4)) 635 + phys_addr = 36; 636 + 629 637 size_or_mask = ~((1 << (phys_addr - PAGE_SHIFT)) - 1); 630 638 size_and_mask = ~size_or_mask & 0xfff00000; 631 639 } else if (boot_cpu_data.x86_vendor == X86_VENDOR_CENTAUR &&
+5
arch/x86_64/kernel/setup.c
··· 995 995 unsigned eax = cpuid_eax(0x80000008); 996 996 c->x86_virt_bits = (eax >> 8) & 0xff; 997 997 c->x86_phys_bits = eax & 0xff; 998 + /* CPUID workaround for Intel 0F34 CPU */ 999 + if (c->x86_vendor == X86_VENDOR_INTEL && 1000 + c->x86 == 0xF && c->x86_model == 0x3 && 1001 + c->x86_mask == 0x4) 1002 + c->x86_phys_bits = 36; 998 1003 } 999 1004 1000 1005 if (c->x86 == 15)