diff options
-rw-r--r-- | arch/x86/include/asm/cacheflush.h | 69 | ||||
-rw-r--r-- | arch/x86/mm/pat.c | 69 |
2 files changed, 69 insertions, 69 deletions
diff --git a/arch/x86/include/asm/cacheflush.h b/arch/x86/include/asm/cacheflush.h index 157644bdf70e..47c8e32f621a 100644 --- a/arch/x86/include/asm/cacheflush.h +++ b/arch/x86/include/asm/cacheflush.h | |||
@@ -5,75 +5,6 @@ | |||
5 | #include <asm-generic/cacheflush.h> | 5 | #include <asm-generic/cacheflush.h> |
6 | #include <asm/special_insns.h> | 6 | #include <asm/special_insns.h> |
7 | 7 | ||
8 | #ifdef CONFIG_X86_PAT | ||
9 | /* | ||
10 | * X86 PAT uses page flags WC and Uncached together to keep track of | ||
11 | * memory type of pages that have backing page struct. X86 PAT supports 3 | ||
12 | * different memory types, _PAGE_CACHE_MODE_WB, _PAGE_CACHE_MODE_WC and | ||
13 | * _PAGE_CACHE_MODE_UC_MINUS and fourth state where page's memory type has not | ||
14 | * been changed from its default (value of -1 used to denote this). | ||
15 | * Note we do not support _PAGE_CACHE_MODE_UC here. | ||
16 | */ | ||
17 | |||
18 | #define _PGMT_DEFAULT 0 | ||
19 | #define _PGMT_WC (1UL << PG_arch_1) | ||
20 | #define _PGMT_UC_MINUS (1UL << PG_uncached) | ||
21 | #define _PGMT_WB (1UL << PG_uncached | 1UL << PG_arch_1) | ||
22 | #define _PGMT_MASK (1UL << PG_uncached | 1UL << PG_arch_1) | ||
23 | #define _PGMT_CLEAR_MASK (~_PGMT_MASK) | ||
24 | |||
25 | static inline enum page_cache_mode get_page_memtype(struct page *pg) | ||
26 | { | ||
27 | unsigned long pg_flags = pg->flags & _PGMT_MASK; | ||
28 | |||
29 | if (pg_flags == _PGMT_DEFAULT) | ||
30 | return -1; | ||
31 | else if (pg_flags == _PGMT_WC) | ||
32 | return _PAGE_CACHE_MODE_WC; | ||
33 | else if (pg_flags == _PGMT_UC_MINUS) | ||
34 | return _PAGE_CACHE_MODE_UC_MINUS; | ||
35 | else | ||
36 | return _PAGE_CACHE_MODE_WB; | ||
37 | } | ||
38 | |||
39 | static inline void set_page_memtype(struct page *pg, | ||
40 | enum page_cache_mode memtype) | ||
41 | { | ||
42 | unsigned long memtype_flags; | ||
43 | unsigned long old_flags; | ||
44 | unsigned long new_flags; | ||
45 | |||
46 | switch (memtype) { | ||
47 | case _PAGE_CACHE_MODE_WC: | ||
48 | memtype_flags = _PGMT_WC; | ||
49 | break; | ||
50 | case _PAGE_CACHE_MODE_UC_MINUS: | ||
51 | memtype_flags = _PGMT_UC_MINUS; | ||
52 | break; | ||
53 | case _PAGE_CACHE_MODE_WB: | ||
54 | memtype_flags = _PGMT_WB; | ||
55 | break; | ||
56 | default: | ||
57 | memtype_flags = _PGMT_DEFAULT; | ||
58 | break; | ||
59 | } | ||
60 | |||
61 | do { | ||
62 | old_flags = pg->flags; | ||
63 | new_flags = (old_flags & _PGMT_CLEAR_MASK) | memtype_flags; | ||
64 | } while (cmpxchg(&pg->flags, old_flags, new_flags) != old_flags); | ||
65 | } | ||
66 | #else | ||
67 | static inline enum page_cache_mode get_page_memtype(struct page *pg) | ||
68 | { | ||
69 | return -1; | ||
70 | } | ||
71 | static inline void set_page_memtype(struct page *pg, | ||
72 | enum page_cache_mode memtype) | ||
73 | { | ||
74 | } | ||
75 | #endif | ||
76 | |||
77 | /* | 8 | /* |
78 | * The set_memory_* API can be used to change various attributes of a virtual | 9 | * The set_memory_* API can be used to change various attributes of a virtual |
79 | * address range. The attributes include: | 10 | * address range. The attributes include: |
diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c index 4c601276a556..25d2c58489e0 100644 --- a/arch/x86/mm/pat.c +++ b/arch/x86/mm/pat.c | |||
@@ -67,6 +67,75 @@ __setup("debugpat", pat_debug_setup); | |||
67 | 67 | ||
68 | static u64 __read_mostly boot_pat_state; | 68 | static u64 __read_mostly boot_pat_state; |
69 | 69 | ||
70 | #ifdef CONFIG_X86_PAT | ||
71 | /* | ||
72 | * X86 PAT uses page flags WC and Uncached together to keep track of | ||
73 | * memory type of pages that have backing page struct. X86 PAT supports 3 | ||
74 | * different memory types, _PAGE_CACHE_MODE_WB, _PAGE_CACHE_MODE_WC and | ||
75 | * _PAGE_CACHE_MODE_UC_MINUS and fourth state where page's memory type has not | ||
76 | * been changed from its default (value of -1 used to denote this). | ||
77 | * Note we do not support _PAGE_CACHE_MODE_UC here. | ||
78 | */ | ||
79 | |||
80 | #define _PGMT_DEFAULT 0 | ||
81 | #define _PGMT_WC (1UL << PG_arch_1) | ||
82 | #define _PGMT_UC_MINUS (1UL << PG_uncached) | ||
83 | #define _PGMT_WB (1UL << PG_uncached | 1UL << PG_arch_1) | ||
84 | #define _PGMT_MASK (1UL << PG_uncached | 1UL << PG_arch_1) | ||
85 | #define _PGMT_CLEAR_MASK (~_PGMT_MASK) | ||
86 | |||
87 | static inline enum page_cache_mode get_page_memtype(struct page *pg) | ||
88 | { | ||
89 | unsigned long pg_flags = pg->flags & _PGMT_MASK; | ||
90 | |||
91 | if (pg_flags == _PGMT_DEFAULT) | ||
92 | return -1; | ||
93 | else if (pg_flags == _PGMT_WC) | ||
94 | return _PAGE_CACHE_MODE_WC; | ||
95 | else if (pg_flags == _PGMT_UC_MINUS) | ||
96 | return _PAGE_CACHE_MODE_UC_MINUS; | ||
97 | else | ||
98 | return _PAGE_CACHE_MODE_WB; | ||
99 | } | ||
100 | |||
101 | static inline void set_page_memtype(struct page *pg, | ||
102 | enum page_cache_mode memtype) | ||
103 | { | ||
104 | unsigned long memtype_flags; | ||
105 | unsigned long old_flags; | ||
106 | unsigned long new_flags; | ||
107 | |||
108 | switch (memtype) { | ||
109 | case _PAGE_CACHE_MODE_WC: | ||
110 | memtype_flags = _PGMT_WC; | ||
111 | break; | ||
112 | case _PAGE_CACHE_MODE_UC_MINUS: | ||
113 | memtype_flags = _PGMT_UC_MINUS; | ||
114 | break; | ||
115 | case _PAGE_CACHE_MODE_WB: | ||
116 | memtype_flags = _PGMT_WB; | ||
117 | break; | ||
118 | default: | ||
119 | memtype_flags = _PGMT_DEFAULT; | ||
120 | break; | ||
121 | } | ||
122 | |||
123 | do { | ||
124 | old_flags = pg->flags; | ||
125 | new_flags = (old_flags & _PGMT_CLEAR_MASK) | memtype_flags; | ||
126 | } while (cmpxchg(&pg->flags, old_flags, new_flags) != old_flags); | ||
127 | } | ||
128 | #else | ||
129 | static inline enum page_cache_mode get_page_memtype(struct page *pg) | ||
130 | { | ||
131 | return -1; | ||
132 | } | ||
133 | static inline void set_page_memtype(struct page *pg, | ||
134 | enum page_cache_mode memtype) | ||
135 | { | ||
136 | } | ||
137 | #endif | ||
138 | |||
70 | enum { | 139 | enum { |
71 | PAT_UC = 0, /* uncached */ | 140 | PAT_UC = 0, /* uncached */ |
72 | PAT_WC = 1, /* Write combining */ | 141 | PAT_WC = 1, /* Write combining */ |