diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c index 011e07e99cd19ce183537882a25754574d1b9d54..74ec2ea4ed3e8c68d130ea1870d700b555882041 100644 --- a/arch/x86/kernel/cpu/mtrr/generic.c +++ b/arch/x86/kernel/cpu/mtrr/generic.c @@ -37,6 +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; #undef MODULE_PARAM_PREFIX #define MODULE_PARAM_PREFIX "mtrr." @@ -138,6 +139,11 @@ u8 mtrr_type_lookup(u64 start, u64 end) } } + if (tom2) { + if (start >= (1ULL<<32) && (end < tom2)) + return MTRR_TYPE_WRBACK; + } + if (prev_match != 0xFF) return prev_match; @@ -206,6 +212,15 @@ void __init get_mtrr_state(void) mtrr_state.def_type = (lo & 0xff); mtrr_state.enabled = (lo & 0xc00) >> 10; + if (amd_special_default_mtrr()) { + unsigned lo, hi; + /* TOP_MEM2 */ + rdmsr(MSR_K8_TOP_MEM2, lo, hi); + tom2 = hi; + tom2 <<= 32; + tom2 |= lo; + tom2 &= 0xffffff8000000ULL; + } if (mtrr_show) { int high_width; @@ -236,6 +251,8 @@ void __init get_mtrr_state(void) else printk(KERN_INFO "MTRR %u disabled\n", i); } + if (tom2) + printk(KERN_INFO "TOM2: %016lx aka %ldM\n", tom2, tom2>>20); } mtrr_state_set = 1; diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c index a6450b3ae759f2ce994bd40deedea2dbfceb4db8..6a1e278d93230de4da44549cf537a33b5b3ff441 100644 --- a/arch/x86/kernel/cpu/mtrr/main.c +++ b/arch/x86/kernel/cpu/mtrr/main.c @@ -627,7 +627,7 @@ early_param("disable_mtrr_trim", disable_mtrr_trim_setup); #define Tom2Enabled (1U << 21) #define Tom2ForceMemTypeWB (1U << 22) -static __init int amd_special_default_mtrr(void) +int __init amd_special_default_mtrr(void) { u32 l, h; diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c index 57a2af36d6ee68f0320c9218610cbe4d6dcfe47d..0648a2225b09e69e207a86a34a9a044fe6663a24 100644 --- a/arch/x86/mm/pat.c +++ b/arch/x86/mm/pat.c @@ -47,6 +47,12 @@ static int pat_known_cpu(void) return 1; } } + if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD && + boot_cpu_data.x86 >= 0xf && boot_cpu_data.x86 <= 0x11) { + if (cpu_has_pat) { + return 1; + } + } pat_wc_enabled = 0; printk(KERN_INFO "CPU and/or kernel does not support PAT.\n"); diff --git a/include/asm-x86/mtrr.h b/include/asm-x86/mtrr.h index ee172296e05662378c8755dc656ecd73b9864630..d3d26625aeaf3d090c80ab12937dcf55e6005124 100644 --- a/include/asm-x86/mtrr.h +++ b/include/asm-x86/mtrr.h @@ -99,6 +99,7 @@ extern void mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi); extern void mtrr_ap_init(void); extern void mtrr_bp_init(void); extern int mtrr_trim_uncached_memory(unsigned long end_pfn); +extern int amd_special_default_mtrr(void); # else static inline u8 mtrr_type_lookup(u64 addr, u64 end) {