1#ifndef _ASM_X86_CACHEFLUSH_H
2#define _ASM_X86_CACHEFLUSH_H
3
4
5#include <asm-generic/cacheflush.h>
6#include <asm/special_insns.h>
7
8#ifdef CONFIG_X86_PAT
9
10
11
12
13
14
15
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
25static inline unsigned long 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_WC;
33 else if (pg_flags == _PGMT_UC_MINUS)
34 return _PAGE_CACHE_UC_MINUS;
35 else
36 return _PAGE_CACHE_WB;
37}
38
39static inline void set_page_memtype(struct page *pg, unsigned long memtype)
40{
41 unsigned long memtype_flags = _PGMT_DEFAULT;
42 unsigned long old_flags;
43 unsigned long new_flags;
44
45 switch (memtype) {
46 case _PAGE_CACHE_WC:
47 memtype_flags = _PGMT_WC;
48 break;
49 case _PAGE_CACHE_UC_MINUS:
50 memtype_flags = _PGMT_UC_MINUS;
51 break;
52 case _PAGE_CACHE_WB:
53 memtype_flags = _PGMT_WB;
54 break;
55 }
56
57 do {
58 old_flags = pg->flags;
59 new_flags = (old_flags & _PGMT_CLEAR_MASK) | memtype_flags;
60 } while (cmpxchg(&pg->flags, old_flags, new_flags) != old_flags);
61}
62#else
63static inline unsigned long get_page_memtype(struct page *pg) { return -1; }
64static inline void set_page_memtype(struct page *pg, unsigned long memtype) { }
65#endif
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95int _set_memory_uc(unsigned long addr, int numpages);
96int _set_memory_wc(unsigned long addr, int numpages);
97int _set_memory_wb(unsigned long addr, int numpages);
98int set_memory_uc(unsigned long addr, int numpages);
99int set_memory_wc(unsigned long addr, int numpages);
100int set_memory_wb(unsigned long addr, int numpages);
101int set_memory_x(unsigned long addr, int numpages);
102int set_memory_nx(unsigned long addr, int numpages);
103int set_memory_ro(unsigned long addr, int numpages);
104int set_memory_rw(unsigned long addr, int numpages);
105int set_memory_np(unsigned long addr, int numpages);
106int set_memory_4k(unsigned long addr, int numpages);
107
108int set_memory_array_uc(unsigned long *addr, int addrinarray);
109int set_memory_array_wc(unsigned long *addr, int addrinarray);
110int set_memory_array_wb(unsigned long *addr, int addrinarray);
111
112int set_pages_array_uc(struct page **pages, int addrinarray);
113int set_pages_array_wc(struct page **pages, int addrinarray);
114int set_pages_array_wb(struct page **pages, int addrinarray);
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136int set_pages_uc(struct page *page, int numpages);
137int set_pages_wb(struct page *page, int numpages);
138int set_pages_x(struct page *page, int numpages);
139int set_pages_nx(struct page *page, int numpages);
140int set_pages_ro(struct page *page, int numpages);
141int set_pages_rw(struct page *page, int numpages);
142
143
144void clflush_cache_range(void *addr, unsigned int size);
145
146#ifdef CONFIG_DEBUG_RODATA
147void mark_rodata_ro(void);
148extern const int rodata_test_data;
149extern int kernel_set_to_readonly;
150void set_kernel_text_rw(void);
151void set_kernel_text_ro(void);
152#else
153static inline void set_kernel_text_rw(void) { }
154static inline void set_kernel_text_ro(void) { }
155#endif
156
157#ifdef CONFIG_DEBUG_RODATA_TEST
158int rodata_test(void);
159#else
160static inline int rodata_test(void)
161{
162 return 0;
163}
164#endif
165
166#endif
167