|
@@ -235,6 +235,7 @@ static void pat_ap_init(u64 pat)
|
|
|
void pat_init(void)
|
|
|
{
|
|
|
u64 pat;
|
|
|
+ struct cpuinfo_x86 *c = &boot_cpu_data;
|
|
|
|
|
|
if (!pat_enabled()) {
|
|
|
/*
|
|
@@ -244,7 +245,7 @@ void pat_init(void)
|
|
|
* has PAT but the "nopat" boot option has been specified. This
|
|
|
* emulated PAT table is used when MSR_IA32_CR_PAT returns 0.
|
|
|
*
|
|
|
- * PTE encoding used:
|
|
|
+ * PTE encoding:
|
|
|
*
|
|
|
* PCD
|
|
|
* |PWT PAT
|
|
@@ -259,21 +260,61 @@ void pat_init(void)
|
|
|
*/
|
|
|
pat = PAT(0, WB) | PAT(1, WT) | PAT(2, UC_MINUS) | PAT(3, UC) |
|
|
|
PAT(4, WB) | PAT(5, WT) | PAT(6, UC_MINUS) | PAT(7, UC);
|
|
|
- } else {
|
|
|
+
|
|
|
+ } else if ((c->x86_vendor == X86_VENDOR_INTEL) &&
|
|
|
+ (((c->x86 == 0x6) && (c->x86_model <= 0xd)) ||
|
|
|
+ ((c->x86 == 0xf) && (c->x86_model <= 0x6)))) {
|
|
|
/*
|
|
|
- * PTE encoding used in Linux:
|
|
|
+ * PAT support with the lower four entries. Intel Pentium 2,
|
|
|
+ * 3, M, and 4 are affected by PAT errata, which makes the
|
|
|
+ * upper four entries unusable. To be on the safe side, we don't
|
|
|
+ * use those.
|
|
|
+ *
|
|
|
+ * PTE encoding:
|
|
|
* PAT
|
|
|
* |PCD
|
|
|
- * ||PWT
|
|
|
- * |||
|
|
|
- * 000 WB _PAGE_CACHE_WB
|
|
|
- * 001 WC _PAGE_CACHE_WC
|
|
|
- * 010 UC- _PAGE_CACHE_UC_MINUS
|
|
|
- * 011 UC _PAGE_CACHE_UC
|
|
|
+ * ||PWT PAT
|
|
|
+ * ||| slot
|
|
|
+ * 000 0 WB : _PAGE_CACHE_MODE_WB
|
|
|
+ * 001 1 WC : _PAGE_CACHE_MODE_WC
|
|
|
+ * 010 2 UC-: _PAGE_CACHE_MODE_UC_MINUS
|
|
|
+ * 011 3 UC : _PAGE_CACHE_MODE_UC
|
|
|
* PAT bit unused
|
|
|
+ *
|
|
|
+ * NOTE: When WT or WP is used, it is redirected to UC- per
|
|
|
+ * the default setup in __cachemode2pte_tbl[].
|
|
|
*/
|
|
|
pat = PAT(0, WB) | PAT(1, WC) | PAT(2, UC_MINUS) | PAT(3, UC) |
|
|
|
PAT(4, WB) | PAT(5, WC) | PAT(6, UC_MINUS) | PAT(7, UC);
|
|
|
+ } else {
|
|
|
+ /*
|
|
|
+ * Full PAT support. We put WT in slot 7 to improve
|
|
|
+ * robustness in the presence of errata that might cause
|
|
|
+ * the high PAT bit to be ignored. This way, a buggy slot 7
|
|
|
+ * access will hit slot 3, and slot 3 is UC, so at worst
|
|
|
+ * we lose performance without causing a correctness issue.
|
|
|
+ * Pentium 4 erratum N46 is an example for such an erratum,
|
|
|
+ * although we try not to use PAT at all on affected CPUs.
|
|
|
+ *
|
|
|
+ * PTE encoding:
|
|
|
+ * PAT
|
|
|
+ * |PCD
|
|
|
+ * ||PWT PAT
|
|
|
+ * ||| slot
|
|
|
+ * 000 0 WB : _PAGE_CACHE_MODE_WB
|
|
|
+ * 001 1 WC : _PAGE_CACHE_MODE_WC
|
|
|
+ * 010 2 UC-: _PAGE_CACHE_MODE_UC_MINUS
|
|
|
+ * 011 3 UC : _PAGE_CACHE_MODE_UC
|
|
|
+ * 100 4 WB : Reserved
|
|
|
+ * 101 5 WC : Reserved
|
|
|
+ * 110 6 UC-: Reserved
|
|
|
+ * 111 7 WT : _PAGE_CACHE_MODE_WT
|
|
|
+ *
|
|
|
+ * The reserved slots are unused, but mapped to their
|
|
|
+ * corresponding types in the presence of PAT errata.
|
|
|
+ */
|
|
|
+ pat = PAT(0, WB) | PAT(1, WC) | PAT(2, UC_MINUS) | PAT(3, UC) |
|
|
|
+ PAT(4, WB) | PAT(5, WC) | PAT(6, UC_MINUS) | PAT(7, WT);
|
|
|
}
|
|
|
|
|
|
if (!boot_cpu_done) {
|