x86, pat: workaround to force PAT usage 30/100730/1
authorVasiliy Ulyanov <v.ulyanov@samsung.com>
Tue, 11 Oct 2016 12:49:04 +0000 (15:49 +0300)
committerSooyoung Ha <yoosah.ha@samsung.com>
Tue, 29 Nov 2016 05:31:15 +0000 (14:31 +0900)
When run under haxm certain CPU features appear inaccesible from guest
and at the moment there seems to be no proper way to set them up from the
host side. The patch allows to forcefully enable x86 Page Attribute
Table and therefore use different memory caching policies at the page
level granularity. PAT significantly improves performance when mmaped
device buffers are accessed.

WARNING: once a proper solution is figured out for haxm case the patch
should be reverted. Currently it is more like a hack to avoid terrible
performance on certain scenarios like decoding high resolution video
directly into the mmaped video buffer.

Change-Id: Ib626a93b2ff16cc8bbdee186cfe67cff6b29e618
Signed-off-by: Vasiliy Ulyanov <v.ulyanov@samsung.com>
Signed-off-by: Sooyoung Ha <yoosah.ha@samsung.com>
arch/x86/mm/pat.c

index 188e3e0..f299c1b 100644 (file)
@@ -68,6 +68,11 @@ static int __init pat_debug_setup(char *str)
 }
 __setup("debugpat", pat_debug_setup);
 
+/*
+ * FIXME This is a hack to force PAT. Currently always enabled.
+ */
+static int __read_mostly __force_pat = 1;
+
 #ifdef CONFIG_X86_PAT
 /*
  * X86 PAT uses page flags arch_1 and uncached together to keep track of
@@ -201,6 +206,9 @@ static void pat_bsp_init(u64 pat)
 {
        u64 tmp_pat;
 
+       if (__force_pat)
+               goto force_pat;
+
        if (!cpu_has_pat) {
                pat_disable("PAT not supported by CPU.");
                return;
@@ -215,6 +223,7 @@ static void pat_bsp_init(u64 pat)
                return;
        }
 
+force_pat:
        wrmsrl(MSR_IA32_CR_PAT, pat);
 
 done:
@@ -223,6 +232,9 @@ done:
 
 static void pat_ap_init(u64 pat)
 {
+       if (__force_pat)
+               goto force_pat;
+
        if (!pat_enabled())
                return;
 
@@ -234,6 +246,7 @@ static void pat_ap_init(u64 pat)
                panic("x86/PAT: PAT enabled, but not supported by secondary CPU\n");
        }
 
+force_pat:
        wrmsrl(MSR_IA32_CR_PAT, pat);
 }
 
@@ -242,6 +255,12 @@ void pat_init(void)
        u64 pat;
        struct cpuinfo_x86 *c = &boot_cpu_data;
 
+       if (__force_pat) {
+               pr_warn("Force x86 PAT\n");
+               setup_force_cpu_cap(X86_FEATURE_PAT);
+               goto force_pat;
+       }
+
        if (!pat_enabled()) {
                /*
                 * No PAT. Emulate the PAT table that corresponds to the two
@@ -292,6 +311,7 @@ void pat_init(void)
                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 {
+force_pat:
                /*
                 * Full PAT support.  We put WT in slot 7 to improve
                 * robustness in the presence of errata that might cause