diff options
author | Shaohua Li <shaohua.li@intel.com> | 2005-11-05 11:25:54 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-11-14 22:55:16 -0500 |
commit | af9c142de94ecf724a18700273bbba390873e072 (patch) | |
tree | 12ecf9850dc75c19cca7a14233d5ba3efe7dbb9d /arch | |
parent | 1d2e6bd86152ab86fb866555281869df340e6c6a (diff) |
[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>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/i386/kernel/cpu/mtrr/main.c | 8 | ||||
-rw-r--r-- | arch/x86_64/kernel/setup.c | 5 |
2 files changed, 13 insertions, 0 deletions
diff --git a/arch/i386/kernel/cpu/mtrr/main.c b/arch/i386/kernel/cpu/mtrr/main.c index dd4ebd6af7e4..1e9db198c440 100644 --- a/arch/i386/kernel/cpu/mtrr/main.c +++ b/arch/i386/kernel/cpu/mtrr/main.c | |||
@@ -626,6 +626,14 @@ void __init mtrr_bp_init(void) | |||
626 | if (cpuid_eax(0x80000000) >= 0x80000008) { | 626 | if (cpuid_eax(0x80000000) >= 0x80000008) { |
627 | u32 phys_addr; | 627 | u32 phys_addr; |
628 | phys_addr = cpuid_eax(0x80000008) & 0xff; | 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 | size_or_mask = ~((1 << (phys_addr - PAGE_SHIFT)) - 1); | 637 | size_or_mask = ~((1 << (phys_addr - PAGE_SHIFT)) - 1); |
630 | size_and_mask = ~size_or_mask & 0xfff00000; | 638 | size_and_mask = ~size_or_mask & 0xfff00000; |
631 | } else if (boot_cpu_data.x86_vendor == X86_VENDOR_CENTAUR && | 639 | } else if (boot_cpu_data.x86_vendor == X86_VENDOR_CENTAUR && |
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c index 2ad3556dda52..476ee034fca2 100644 --- a/arch/x86_64/kernel/setup.c +++ b/arch/x86_64/kernel/setup.c | |||
@@ -995,6 +995,11 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c) | |||
995 | unsigned eax = cpuid_eax(0x80000008); | 995 | unsigned eax = cpuid_eax(0x80000008); |
996 | c->x86_virt_bits = (eax >> 8) & 0xff; | 996 | c->x86_virt_bits = (eax >> 8) & 0xff; |
997 | c->x86_phys_bits = eax & 0xff; | 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 | if (c->x86 == 15) | 1005 | if (c->x86 == 15) |