Messages in this thread Patch in this message | | | Date | Thu, 21 Aug 2008 20:24:24 -0700 | From | "Yinghai Lu" <> | Subject | Re: [Bug 11388] New: 2.6.27-rc3 warns about MTRR range; only 3 of 16gb of memory is usable |
| |
On Thu, Aug 21, 2008 at 7:26 PM, Yinghai Lu <yhlu.kernel@gmail.com> wrote: > On Thu, Aug 21, 2008 at 7:15 PM, Joshua Hoblitt <josh@hoblitt.com> wrote: >> On Thu, Aug 21, 2008 at 06:55:58PM -0700, Yinghai Lu wrote: >> address sizes : 38 bits physical, 48 bits virtual > > good, the root cause is your bios not set mask correctly... > > it should set var mtrr like > > [ 0.429971] MSR00000200: 00000000d0000000 > [ 0.433305] MSR00000201: 0000000ff0000800 > ==> [ 0.433305] MSR00000201: 0000003ff0000800 > > [ 0.436638] MSR00000202: 00000000e0000000 > [ 0.439971] MSR00000203: 0000000fe0000800 > ==> [ 0.439971] MSR00000203: 0000003fe0000800 > > [ 0.443304] MSR00000204: 0000000000000006 > [ 0.446637] MSR00000205: 0000000c00000800 > ==> [ 0.446637] MSR00000205: 0000003c00000800 > > [ 0.449970] MSR00000206: 0000000400000006 > [ 0.453303] MSR00000207: 0000000fe0000800 > ==>[ 0.453303] MSR00000207: 0000003fe0000800 > > [ 0.456636] MSR00000208: 0000000420000006 > [ 0.459970] MSR00000209: 0000000ff0000800 > ==> [ 0.459970] MSR00000209: 0000003ff0000800 > > you may talk to your BIOS vendor or system vendor to request one new > updated BIOS. >
or please try attached workaround patch. hope it works.
Ingo, if it works, we need to push it for 2.6.27
YH [PATCH] x86: workaroun mtrr mask setting
Some BIOS doesn't set mtrr mask correctly, workaround it be prefix 111
Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c index 509bd3d..a17d5ba 100644 --- a/arch/x86/kernel/cpu/mtrr/generic.c +++ b/arch/x86/kernel/cpu/mtrr/generic.c @@ -379,6 +379,7 @@ static void generic_get_mtrr(unsigned int reg, unsigned long *base, unsigned long *size, mtrr_type *type) { unsigned int mask_lo, mask_hi, base_lo, base_hi; + unsigned int tmp, hi; rdmsr(MTRRphysMask_MSR(reg), mask_lo, mask_hi); if ((mask_lo & 0x800) == 0) { @@ -392,8 +393,18 @@ static void generic_get_mtrr(unsigned int reg, unsigned long *base, rdmsr(MTRRphysBase_MSR(reg), base_lo, base_hi); /* Work out the shifted address mask. */ - mask_lo = size_or_mask | mask_hi << (32 - PAGE_SHIFT) - | mask_lo >> PAGE_SHIFT; + tmp = mask_hi << (32 - PAGE_SHIFT) | mask_lo >> PAGE_SHIFT; + mask_lo = size_or_mask | tmp; + /* expend tmp with high bits to all 1s*/ + hi = fls(tmp); + if (hi > 0) { + tmp |= ~((1<<(hi - 1)) - 1); + + if (tmp != mask_lo) { + WARN_ON("You BIOS mask set is wrong, complain to vendor\n"); + mask_lo = tmp; + } + } /* This works correctly if size is a power of two, i.e. a contiguous range. */ | |