On Tue, 2016-03-15 at 01:29 +0100, Luis R. Rodriguez wrote:
> I like this approach more as it stuff more PAT setup on its own type
> of calls, but:
> 
> On Sat, Mar 12, 2016 at 12:55:44PM +0100, Borislav Petkov wrote:
> > diff --git a/arch/x86/kernel/cpu/mtrr/main.c
> > b/arch/x86/kernel/cpu/mtrr/main.c
> > index 10f8d4796240..5c442b4bd52a 100644
> > --- a/arch/x86/kernel/cpu/mtrr/main.c
> > +++ b/arch/x86/kernel/cpu/mtrr/main.c
> > @@ -759,8 +761,11 @@ void __init mtrr_bp_init(void)
> >             }
> >     }
> >  
> > -   if (!mtrr_enabled())
> > +   if (!__mtrr_enabled) {
> >             pr_info("MTRR: Disabled\n");
> > +           pat_disable("PAT disabled by MTRR");
> > +           pat_setup();
> > +   }
> >  }
> 
> This hunk would break PAT on Xen.

Can you try the attached patches?  They apply on top of my original patch-
set.  With this change, PAT code generally supports Xen, and the PAT init
code in Xen is now removed.  If they look OK, I will reorganize the patch
series.

Thanks,
-Toshi
From: Toshi Kani <toshi.k...@hpe.com>

Add support of PAT emulation that matches with the PAT MSR.

---
 arch/x86/mm/pat.c |   73 +++++++++++++++++++++++++++++++----------------------
 1 file changed, 43 insertions(+), 30 deletions(-)

diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c
index 1ff8aa9..565a478 100644
--- a/arch/x86/mm/pat.c
+++ b/arch/x86/mm/pat.c
@@ -40,7 +40,7 @@
 static bool boot_cpu_done;
 
 static int __read_mostly __pat_enabled = IS_ENABLED(CONFIG_X86_PAT);
-static void pat_disable_init(void);
+static void pat_emu_init(void);
 
 void pat_disable(const char *reason)
 {
@@ -52,7 +52,7 @@ void pat_disable(const char *reason)
 	__pat_enabled = 0;
 	pr_info("x86/PAT: %s\n", reason);
 
-	pat_disable_init();
+	pat_emu_init();
 }
 
 static int __init nopat(char *str)
@@ -239,40 +239,53 @@ static void pat_ap_init(u64 pat)
 	wrmsrl(MSR_IA32_CR_PAT, pat);
 }
 
-static void pat_disable_init(void)
+static void pat_emu_init(void)
 {
-	u64 pat;
-	static int disable_init_done;
+	u64 pat = 0;
+	static int emu_init_done;
 
-	if (disable_init_done)
+	if (emu_init_done)
 		return;
 
-	/*
-	 * No PAT. Emulate the PAT table that corresponds to the two
-	 * cache bits, PWT (Write Through) and PCD (Cache Disable). This
-	 * setup is the same as the BIOS default setup when the system
-	 * 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:
-	 *
-	 *       PCD
-	 *       |PWT  PAT
-	 *       ||    slot
-	 *       00    0    WB : _PAGE_CACHE_MODE_WB
-	 *       01    1    WT : _PAGE_CACHE_MODE_WT
-	 *       10    2    UC-: _PAGE_CACHE_MODE_UC_MINUS
-	 *       11    3    UC : _PAGE_CACHE_MODE_UC
-	 *
-	 * NOTE: When WC or WP is used, it is redirected to UC- per
-	 * the default setup in __cachemode2pte_tbl[].
-	 */
-	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);
+	if (cpu_has_pat) {
+		/*
+		 * CPU supports PAT. Initialize the PAT table to match with
+		 * the PAT MSR value. This setup is used by "nopat" boot
+		 * option, or by virtual machine environments which do not
+		 * support MTRRs but support PAT.
+		 *
+		 * If the MSR returns 0, it is considered invalid and emulate
+		 * as No PAT.
+		 */
+		rdmsrl(MSR_IA32_CR_PAT, pat);
+	}
+
+	if (!pat) {
+		/*
+		 * No PAT. Emulate the PAT table that corresponds to the two
+		 * cache bits, PWT (Write Through) and PCD (Cache Disable).
+		 * This setup is also the same as the BIOS default setup.
+		 *
+		 * PTE encoding:
+		 *
+		 *       PCD
+		 *       |PWT  PAT
+		 *       ||    slot
+		 *       00    0    WB : _PAGE_CACHE_MODE_WB
+		 *       01    1    WT : _PAGE_CACHE_MODE_WT
+		 *       10    2    UC-: _PAGE_CACHE_MODE_UC_MINUS
+		 *       11    3    UC : _PAGE_CACHE_MODE_UC
+		 *
+		 * NOTE: When WC or WP is used, it is redirected to UC- per
+		 * the default setup in __cachemode2pte_tbl[].
+		 */
+		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);
+	}
 
 	pat_init_cache_modes(pat);
 
-	disable_init_done = 1;
+	emu_init_done = 1;
 }
 
 void pat_init(void)
@@ -281,7 +294,7 @@ void pat_init(void)
 	struct cpuinfo_x86 *c = &boot_cpu_data;
 
 	if (!pat_enabled()) {
-		pat_disable_init();
+		pat_emu_init();
 		return;
 	}
 
From: Toshi Kani <toshi.k...@hpe.com>

Delete the PAT table initialization code from Xen as this case
is now supported by PAT.

---
 arch/x86/include/asm/mtrr.h     |    2 +-
 arch/x86/kernel/cpu/mtrr/main.c |    4 ++--
 arch/x86/xen/enlighten.c        |    9 ---------
 3 files changed, 3 insertions(+), 12 deletions(-)

diff --git a/arch/x86/include/asm/mtrr.h b/arch/x86/include/asm/mtrr.h
index a965e74..77420c3 100644
--- a/arch/x86/include/asm/mtrr.h
+++ b/arch/x86/include/asm/mtrr.h
@@ -86,7 +86,7 @@ static inline void mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi)
 }
 static inline void mtrr_bp_init(void)
 {
-	pat_disable("PAT disabled by MTRR");
+	pat_disable("PAT emulation");
 }
 
 #define mtrr_ap_init() do {} while (0)
diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c
index d9e91f1..e10fba4 100644
--- a/arch/x86/kernel/cpu/mtrr/main.c
+++ b/arch/x86/kernel/cpu/mtrr/main.c
@@ -767,10 +767,10 @@ void __init mtrr_bp_init(void)
 
 		/*
 		 * PAT initialization relies on MTRR's rendezvous handler.
-		 * Disable PAT until the handler can initialize both features
+		 * Emulate PAT until the handler can initialize both features
 		 * independently.
 		 */
-		pat_disable("PAT disabled by MTRR");
+		pat_disable("PAT emulation");
 	}
 }
 
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index d09e4c9..c883f11 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -74,7 +74,6 @@
 #include <asm/mach_traps.h>
 #include <asm/mwait.h>
 #include <asm/pci_x86.h>
-#include <asm/pat.h>
 #include <asm/cpu.h>
 
 #ifdef CONFIG_ACPI
@@ -1510,7 +1509,6 @@ asmlinkage __visible void __init xen_start_kernel(void)
 {
 	struct physdev_set_iopl set_iopl;
 	unsigned long initrd_start = 0;
-	u64 pat;
 	int rc;
 
 	if (!xen_start_info)
@@ -1617,13 +1615,6 @@ asmlinkage __visible void __init xen_start_kernel(void)
 				   xen_start_info->nr_pages);
 	xen_reserve_special_pages();
 
-	/*
-	 * Modify the cache mode translation tables to match Xen's PAT
-	 * configuration.
-	 */
-	rdmsrl(MSR_IA32_CR_PAT, pat);
-	pat_init_cache_modes(pat);
-
 	/* keep using Xen gdt for now; no urgent need to change it */
 
 #ifdef CONFIG_X86_32
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

Reply via email to