x86, pat: workaround to force PAT usage
authorVasiliy Ulyanov <v.ulyanov@samsung.com>
Wed, 9 Dec 2015 14:00:38 +0000 (17:00 +0300)
committersung min Ha <sungmin82.ha@samsung.com>
Wed, 27 Jan 2016 05:14:10 +0000 (14:14 +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: Ie810a29d61379e57ed10efc0697f9fc010f85f33
Signed-off-by: Vasiliy Ulyanov <v.ulyanov@samsung.com>
(cherry picked from commit 7aaf8838c358d7e745727e0281ae3acbd9e81afd)

arch/x86/mm/pat.c

index 657438858e8358745484c828158634fba41a5b1c..913cd1947d6498eff16d7742c1c82623736aa89d 100644 (file)
@@ -54,6 +54,14 @@ static inline void pat_disable(const char *reason)
 }
 #endif
 
+static int __read_mostly force_pat;
+
+static int __init force_pat_setup(char *str)
+{
+       force_pat = 1;
+       return 0;
+}
+early_param("force_pat", force_pat_setup);
 
 int pat_debug_enable;
 
@@ -85,9 +93,18 @@ void pat_init(void)
        if (!pat_enabled)
                return;
 
+force_retry:
        if (!cpu_has_pat) {
                if (!boot_pat_state) {
-                       pat_disable("PAT not supported by CPU.");
+                       if (force_pat) {
+                               printk(KERN_WARNING "Force x86 PAT on cpu %d\n",
+                                      smp_processor_id());
+                               setup_force_cpu_cap(X86_FEATURE_PAT);
+                               force_pat = 0;
+                               goto force_retry;
+                       } else {
+                               pat_disable("PAT not supported by CPU.");
+                       }
                        return;
                } else {
                        /*