x86: mtrr cleanup for converting continuous to discrete layout, v8
some BIOS like to use continus MTRR layout, and X driver can not add WB entries for graphical cards when 4g or more RAM installed. the patch will change MTRR to discrete. mtrr_chunk_size= could be used to have smaller continuous block to hold holes. default is 256m, could be set according to size of graphics card memory. mtrr_gran_size= could be used to send smallest mtrr block to avoid run out of MTRRs v2: fix -1 for UC checking v3: default to disable, and need use enable_mtrr_cleanup to enable this feature skip the var state change warning. remove next_basek in range_to_mtrr() v4: correct warning mask. v5: CONFIG_MTRR_SANITIZER v6: fix 1g, 2g, 512 aligment with extra hole v7: gran_sizek to prevent running out of MTRRs. v8: fix hole_basek caculation caused when removing next_basek gran_sizek using when basek is 0. need to apply [PATCH] x86: fix trimming e820 with MTRR holes. right after this one. Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
This commit is contained in:

committed by
Thomas Gleixner

parent
0dbfafa5fc
commit
95ffa2438d
@@ -37,7 +37,7 @@ static struct fixed_range_block fixed_range_blocks[] = {
|
||||
static unsigned long smp_changes_mask;
|
||||
static struct mtrr_state mtrr_state = {};
|
||||
static int mtrr_state_set;
|
||||
static u64 tom2;
|
||||
u64 mtrr_tom2;
|
||||
|
||||
#undef MODULE_PARAM_PREFIX
|
||||
#define MODULE_PARAM_PREFIX "mtrr."
|
||||
@@ -139,8 +139,8 @@ u8 mtrr_type_lookup(u64 start, u64 end)
|
||||
}
|
||||
}
|
||||
|
||||
if (tom2) {
|
||||
if (start >= (1ULL<<32) && (end < tom2))
|
||||
if (mtrr_tom2) {
|
||||
if (start >= (1ULL<<32) && (end < mtrr_tom2))
|
||||
return MTRR_TYPE_WRBACK;
|
||||
}
|
||||
|
||||
@@ -158,6 +158,20 @@ get_mtrr_var_range(unsigned int index, struct mtrr_var_range *vr)
|
||||
rdmsr(MTRRphysMask_MSR(index), vr->mask_lo, vr->mask_hi);
|
||||
}
|
||||
|
||||
/* fill the MSR pair relating to a var range */
|
||||
void fill_mtrr_var_range(unsigned int index,
|
||||
u32 base_lo, u32 base_hi, u32 mask_lo, u32 mask_hi)
|
||||
{
|
||||
struct mtrr_var_range *vr;
|
||||
|
||||
vr = mtrr_state.var_ranges;
|
||||
|
||||
vr[index].base_lo = base_lo;
|
||||
vr[index].base_hi = base_hi;
|
||||
vr[index].mask_lo = mask_lo;
|
||||
vr[index].mask_hi = mask_hi;
|
||||
}
|
||||
|
||||
static void
|
||||
get_fixed_ranges(mtrr_type * frs)
|
||||
{
|
||||
@@ -216,10 +230,10 @@ void __init get_mtrr_state(void)
|
||||
unsigned low, high;
|
||||
/* TOP_MEM2 */
|
||||
rdmsr(MSR_K8_TOP_MEM2, low, high);
|
||||
tom2 = high;
|
||||
tom2 <<= 32;
|
||||
tom2 |= low;
|
||||
tom2 &= 0xffffff8000000ULL;
|
||||
mtrr_tom2 = high;
|
||||
mtrr_tom2 <<= 32;
|
||||
mtrr_tom2 |= low;
|
||||
mtrr_tom2 &= 0xffffff8000000ULL;
|
||||
}
|
||||
if (mtrr_show) {
|
||||
int high_width;
|
||||
@@ -251,9 +265,9 @@ void __init get_mtrr_state(void)
|
||||
else
|
||||
printk(KERN_INFO "MTRR %u disabled\n", i);
|
||||
}
|
||||
if (tom2) {
|
||||
if (mtrr_tom2) {
|
||||
printk(KERN_INFO "TOM2: %016llx aka %lldM\n",
|
||||
tom2, tom2>>20);
|
||||
mtrr_tom2, mtrr_tom2>>20);
|
||||
}
|
||||
}
|
||||
mtrr_state_set = 1;
|
||||
|
Reference in New Issue
Block a user