aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/cpu/mtrr
diff options
context:
space:
mode:
authorYinghai Lu <yinghai@kernel.org>2009-03-16 19:33:59 -0400
committerIngo Molnar <mingo@elte.hu>2009-03-17 05:47:47 -0400
commitf0348c438c9ea156194d31fadde4a9e75522196f (patch)
treee06511311bbe5ca161526f9ab494765efe628413 /arch/x86/kernel/cpu/mtrr
parentd4c90e37a21154c1910b2646e9544bdd32d5bc3a (diff)
x86: MTRR workaround for system with stange var MTRRs
Impact: don't trim e820 according to wrong mtrr Ozan reports that his server emits strange warning. it turns out the BIOS sets the MTRRs incorrectly. Ignore those strange ranges, and don't trim e820, just emit one warning about BIOS Reported-by: Ozan Çağlayan <ozan@pardus.org.tr> Signed-off-by: Yinghai Lu <yinghai@kernel.org> LKML-Reference: <49BEE1E7.7020706@kernel.org> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/cpu/mtrr')
-rw-r--r--arch/x86/kernel/cpu/mtrr/cleanup.c11
-rw-r--r--arch/x86/kernel/cpu/mtrr/main.c16
-rw-r--r--arch/x86/kernel/cpu/mtrr/mtrr.h1
3 files changed, 20 insertions, 8 deletions
diff --git a/arch/x86/kernel/cpu/mtrr/cleanup.c b/arch/x86/kernel/cpu/mtrr/cleanup.c
index 58b58bbf7eb3..f4f89fbc228f 100644
--- a/arch/x86/kernel/cpu/mtrr/cleanup.c
+++ b/arch/x86/kernel/cpu/mtrr/cleanup.c
@@ -189,6 +189,17 @@ x86_get_mtrr_mem_range(struct res_range *range, int nr_range,
189 if (!size) 189 if (!size)
190 continue; 190 continue;
191 base = range_state[i].base_pfn; 191 base = range_state[i].base_pfn;
192 if (base < (1<<(20-PAGE_SHIFT)) && mtrr_state.have_fixed &&
193 (mtrr_state.enabled & 1)) {
194 /* Var MTRR contains UC entry below 1M? Skip it: */
195 printk(KERN_WARNING "WARNING: BIOS bug: VAR MTRR %d "
196 "contains strange UC entry under 1M, check "
197 "with your system vendor!\n", i);
198 if (base + size <= (1<<(20-PAGE_SHIFT)))
199 continue;
200 size -= (1<<(20-PAGE_SHIFT)) - base;
201 base = 1<<(20-PAGE_SHIFT);
202 }
192 subtract_range(range, base, base + size - 1); 203 subtract_range(range, base, base + size - 1);
193 } 204 }
194 if (extra_remove_size) 205 if (extra_remove_size)
diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c
index 5c2e266f41d7..03cda01f57c7 100644
--- a/arch/x86/kernel/cpu/mtrr/main.c
+++ b/arch/x86/kernel/cpu/mtrr/main.c
@@ -574,7 +574,7 @@ struct mtrr_value {
574 unsigned long lsize; 574 unsigned long lsize;
575}; 575};
576 576
577static struct mtrr_value mtrr_state[MTRR_MAX_VAR_RANGES]; 577static struct mtrr_value mtrr_value[MTRR_MAX_VAR_RANGES];
578 578
579static int mtrr_save(struct sys_device * sysdev, pm_message_t state) 579static int mtrr_save(struct sys_device * sysdev, pm_message_t state)
580{ 580{
@@ -582,9 +582,9 @@ static int mtrr_save(struct sys_device * sysdev, pm_message_t state)
582 582
583 for (i = 0; i < num_var_ranges; i++) { 583 for (i = 0; i < num_var_ranges; i++) {
584 mtrr_if->get(i, 584 mtrr_if->get(i,
585 &mtrr_state[i].lbase, 585 &mtrr_value[i].lbase,
586 &mtrr_state[i].lsize, 586 &mtrr_value[i].lsize,
587 &mtrr_state[i].ltype); 587 &mtrr_value[i].ltype);
588 } 588 }
589 return 0; 589 return 0;
590} 590}
@@ -594,11 +594,11 @@ static int mtrr_restore(struct sys_device * sysdev)
594 int i; 594 int i;
595 595
596 for (i = 0; i < num_var_ranges; i++) { 596 for (i = 0; i < num_var_ranges; i++) {
597 if (mtrr_state[i].lsize) 597 if (mtrr_value[i].lsize)
598 set_mtrr(i, 598 set_mtrr(i,
599 mtrr_state[i].lbase, 599 mtrr_value[i].lbase,
600 mtrr_state[i].lsize, 600 mtrr_value[i].lsize,
601 mtrr_state[i].ltype); 601 mtrr_value[i].ltype);
602 } 602 }
603 return 0; 603 return 0;
604} 604}
diff --git a/arch/x86/kernel/cpu/mtrr/mtrr.h b/arch/x86/kernel/cpu/mtrr/mtrr.h
index 6710e93021a7..77f67f7b347a 100644
--- a/arch/x86/kernel/cpu/mtrr/mtrr.h
+++ b/arch/x86/kernel/cpu/mtrr/mtrr.h
@@ -79,6 +79,7 @@ extern struct mtrr_ops * mtrr_if;
79 79
80extern unsigned int num_var_ranges; 80extern unsigned int num_var_ranges;
81extern u64 mtrr_tom2; 81extern u64 mtrr_tom2;
82extern struct mtrr_state_type mtrr_state;
82 83
83void mtrr_state_warn(void); 84void mtrr_state_warn(void);
84const char *mtrr_attrib_to_str(int x); 85const char *mtrr_attrib_to_str(int x);