diff --git a/arch/i386/kernel/cpu/mtrr/main.c b/arch/i386/kernel/cpu/mtrr/main.c index 1cf466d..b4b3ea8 100644 --- a/arch/i386/kernel/cpu/mtrr/main.c +++ b/arch/i386/kernel/cpu/mtrr/main.c @@ -38,8 +38,8 @@ #include #include +#include #include - #include #include #include @@ -47,7 +47,8 @@ u32 num_var_ranges = 0; -unsigned int *usage_table; +#define MAX_MTRR_RANGES 255 +unsigned int usage_table[MAX_MTRR_RANGES]; static DEFINE_MUTEX(mtrr_mutex); u64 size_or_mask, size_and_mask; @@ -121,11 +122,6 @@ static void __init init_table(void) int i, max; max = num_var_ranges; - if ((usage_table = kmalloc(max * sizeof *usage_table, GFP_KERNEL)) - == NULL) { - printk(KERN_ERR "mtrr: could not allocate\n"); - return; - } for (i = 0; i < max; i++) usage_table[i] = 1; } @@ -631,6 +627,29 @@ static struct sysdev_driver mtrr_sysdev_driver = { .resume = mtrr_restore, }; +void __init mtrr_trim_uncached_memory(void) +{ + unsigned long i, base, size, highest_addr = 0; + mtrr_type type; + + /* Find highest cached pfn */ + for (i = 0; i < num_var_ranges; i++) { + mtrr_if->get(i, &base, &size, &type); + if (type != MTRR_TYPE_WRBACK) + continue; + base <<= PAGE_SHIFT; + size <<= PAGE_SHIFT; + if (highest_addr < base + size) + highest_addr = base + size; + } + + if ((highest_addr >> PAGE_SHIFT) != end_pfn) { + printk(KERN_WARNING "Warning: MTRRs don't cover all of " + "memory, trimmed %ld pages\n", end_pfn - + (highest_addr >> PAGE_SHIFT)); + end_pfn = highest_addr >> PAGE_SHIFT; + } +} /** * mtrr_bp_init - initialize mtrrs on the boot CPU diff --git a/arch/x86_64/kernel/bugs.c b/arch/x86_64/kernel/bugs.c index c3c6b91..c138eac 100644 --- a/arch/x86_64/kernel/bugs.c +++ b/arch/x86_64/kernel/bugs.c @@ -14,7 +14,6 @@ void __init check_bugs(void) { identify_cpu(&boot_cpu_data); - mtrr_bp_init(); #if !defined(CONFIG_SMP) printk("CPU: "); print_cpu_info(&boot_cpu_data); diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c index eb6524f..409b63c 100644 --- a/arch/x86_64/kernel/setup.c +++ b/arch/x86_64/kernel/setup.c @@ -266,6 +266,10 @@ void __init setup_arch(char **cmdline_p) * we are rounding upwards: */ end_pfn = e820_end_of_ram(); + /* Trim memory not covered by WB MTRRs */ + mtrr_bp_init(); + mtrr_trim_uncached_memory(); + num_physpages = end_pfn; check_efer(); diff --git a/include/asm-i386/mtrr.h b/include/asm-i386/mtrr.h diff --git a/include/asm-x86_64/mtrr.h b/include/asm-x86_64/mtrr.h index b557c48..cc62bd8 100644 --- a/include/asm-x86_64/mtrr.h +++ b/include/asm-x86_64/mtrr.h @@ -78,6 +78,7 @@ extern int mtrr_add_page (unsigned long base, unsigned long size, unsigned int type, char increment); extern int mtrr_del (int reg, unsigned long base, unsigned long size); extern int mtrr_del_page (int reg, unsigned long base, unsigned long size); +extern void mtrr_trim_uncached_memory(void); # else static __inline__ int mtrr_add (unsigned long base, unsigned long size, unsigned int type, char increment)