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#include <asm/uaccess.h>
8
9#ifdef CONFIG_X86_PAT
10
11
12
13
14
15
16
17
18
19#define _PGMT_DEFAULT 0
20#define _PGMT_WC (1UL << PG_arch_1)
21#define _PGMT_UC_MINUS (1UL << PG_uncached)
22#define _PGMT_WB (1UL << PG_uncached | 1UL << PG_arch_1)
23#define _PGMT_MASK (1UL << PG_uncached | 1UL << PG_arch_1)
24#define _PGMT_CLEAR_MASK (~_PGMT_MASK)
25
26static inline unsigned long get_page_memtype(struct page *pg)
27{
28 unsigned long pg_flags = pg->flags & _PGMT_MASK;
29
30 if (pg_flags == _PGMT_DEFAULT)
31 return -1;
32 else if (pg_flags == _PGMT_WC)
33 return _PAGE_CACHE_WC;
34 else if (pg_flags == _PGMT_UC_MINUS)
35 return _PAGE_CACHE_UC_MINUS;
36 else
37 return _PAGE_CACHE_WB;
38}
39
40static inline void set_page_memtype(struct page *pg, unsigned long memtype)
41{
42 unsigned long memtype_flags = _PGMT_DEFAULT;
43 unsigned long old_flags;
44 unsigned long new_flags;
45
46 switch (memtype) {
47 case _PAGE_CACHE_WC:
48 memtype_flags = _PGMT_WC;
49 break;
50 case _PAGE_CACHE_UC_MINUS:
51 memtype_flags = _PGMT_UC_MINUS;
52 break;
53 case _PAGE_CACHE_WB:
54 memtype_flags = _PGMT_WB;
55 break;
56 }
57
58 do {
59 old_flags = pg->flags;
60 new_flags = (old_flags & _PGMT_CLEAR_MASK) | memtype_flags;
61 } while (cmpxchg(&pg->flags, old_flags, new_flags) != old_flags);
62}
63#else
64static inline unsigned long get_page_memtype(struct page *pg) { return -1; }
65static inline void set_page_memtype(struct page *pg, unsigned long memtype) { }
66#endif
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
95
96int _set_memory_uc(unsigned long addr, int numpages);
97int _set_memory_wc(unsigned long addr, int numpages);
98int _set_memory_wb(unsigned long addr, int numpages);
99int set_memory_uc(unsigned long addr, int numpages);
100int set_memory_wc(unsigned long addr, int numpages);
101int set_memory_wb(unsigned long addr, int numpages);
102int set_memory_x(unsigned long addr, int numpages);
103int set_memory_nx(unsigned long addr, int numpages);
104int set_memory_ro(unsigned long addr, int numpages);
105int set_memory_rw(unsigned long addr, int numpages);
106int set_memory_np(unsigned long addr, int numpages);
107int set_memory_4k(unsigned long addr, int numpages);
108
109int set_memory_array_uc(unsigned long *addr, int addrinarray);
110int set_memory_array_wc(unsigned long *addr, int addrinarray);
111int set_memory_array_wb(unsigned long *addr, int addrinarray);
112
113int set_pages_array_uc(struct page **pages, int addrinarray);
114int set_pages_array_wc(struct page **pages, int addrinarray);
115int set_pages_array_wb(struct page **pages, int addrinarray);
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137int set_pages_uc(struct page *page, int numpages);
138int set_pages_wb(struct page *page, int numpages);
139int set_pages_x(struct page *page, int numpages);
140int set_pages_nx(struct page *page, int numpages);
141int set_pages_ro(struct page *page, int numpages);
142int set_pages_rw(struct page *page, int numpages);
143
144
145void clflush_cache_range(void *addr, unsigned int size);
146
147#define mmio_flush_range(addr, size) clflush_cache_range(addr, size)
148
149#ifdef CONFIG_DEBUG_RODATA
150void mark_rodata_ro(void);
151extern const int rodata_test_data;
152extern int kernel_set_to_readonly;
153void set_kernel_text_rw(void);
154void set_kernel_text_ro(void);
155#else
156static inline void set_kernel_text_rw(void) { }
157static inline void set_kernel_text_ro(void) { }
158#endif
159
160#ifdef CONFIG_DEBUG_RODATA_TEST
161int rodata_test(void);
162#else
163static inline int rodata_test(void)
164{
165 return 0;
166}
167#endif
168
169#endif
170