1 #include <linux/kernel.h>
2 #include <linux/string.h>
3 #include <linux/mm.h>
4 #include <linux/highmem.h>
5 #include <linux/page_ext.h>
6 #include <linux/poison.h>
7 #include <linux/ratelimit.h>
8 
9 static bool page_poisoning_enabled __read_mostly;
10 
need_page_poisoning(void)11 static bool need_page_poisoning(void)
12 {
13 	if (!debug_pagealloc_enabled())
14 		return false;
15 
16 	return true;
17 }
18 
init_page_poisoning(void)19 static void init_page_poisoning(void)
20 {
21 	if (!debug_pagealloc_enabled())
22 		return;
23 
24 	page_poisoning_enabled = true;
25 }
26 
27 struct page_ext_operations page_poisoning_ops = {
28 	.need = need_page_poisoning,
29 	.init = init_page_poisoning,
30 };
31 
set_page_poison(struct page * page)32 static inline void set_page_poison(struct page *page)
33 {
34 	struct page_ext *page_ext;
35 
36 	page_ext = lookup_page_ext(page);
37 	__set_bit(PAGE_EXT_DEBUG_POISON, &page_ext->flags);
38 }
39 
clear_page_poison(struct page * page)40 static inline void clear_page_poison(struct page *page)
41 {
42 	struct page_ext *page_ext;
43 
44 	page_ext = lookup_page_ext(page);
45 	__clear_bit(PAGE_EXT_DEBUG_POISON, &page_ext->flags);
46 }
47 
page_poison(struct page * page)48 static inline bool page_poison(struct page *page)
49 {
50 	struct page_ext *page_ext;
51 
52 	page_ext = lookup_page_ext(page);
53 	return test_bit(PAGE_EXT_DEBUG_POISON, &page_ext->flags);
54 }
55 
poison_page(struct page * page)56 static void poison_page(struct page *page)
57 {
58 	void *addr = kmap_atomic(page);
59 
60 	set_page_poison(page);
61 	memset(addr, PAGE_POISON, PAGE_SIZE);
62 	kunmap_atomic(addr);
63 }
64 
poison_pages(struct page * page,int n)65 static void poison_pages(struct page *page, int n)
66 {
67 	int i;
68 
69 	for (i = 0; i < n; i++)
70 		poison_page(page + i);
71 }
72 
single_bit_flip(unsigned char a,unsigned char b)73 static bool single_bit_flip(unsigned char a, unsigned char b)
74 {
75 	unsigned char error = a ^ b;
76 
77 	return error && !(error & (error - 1));
78 }
79 
check_poison_mem(unsigned char * mem,size_t bytes)80 static void check_poison_mem(unsigned char *mem, size_t bytes)
81 {
82 	static DEFINE_RATELIMIT_STATE(ratelimit, 5 * HZ, 10);
83 	unsigned char *start;
84 	unsigned char *end;
85 
86 	start = memchr_inv(mem, PAGE_POISON, bytes);
87 	if (!start)
88 		return;
89 
90 	for (end = mem + bytes - 1; end > start; end--) {
91 		if (*end != PAGE_POISON)
92 			break;
93 	}
94 
95 	if (!__ratelimit(&ratelimit))
96 		return;
97 	else if (start == end && single_bit_flip(*start, PAGE_POISON))
98 		printk(KERN_ERR "pagealloc: single bit error\n");
99 	else
100 		printk(KERN_ERR "pagealloc: memory corruption\n");
101 
102 	print_hex_dump(KERN_ERR, "", DUMP_PREFIX_ADDRESS, 16, 1, start,
103 			end - start + 1, 1);
104 	dump_stack();
105 }
106 
unpoison_page(struct page * page)107 static void unpoison_page(struct page *page)
108 {
109 	void *addr;
110 
111 	if (!page_poison(page))
112 		return;
113 
114 	addr = kmap_atomic(page);
115 	check_poison_mem(addr, PAGE_SIZE);
116 	clear_page_poison(page);
117 	kunmap_atomic(addr);
118 }
119 
unpoison_pages(struct page * page,int n)120 static void unpoison_pages(struct page *page, int n)
121 {
122 	int i;
123 
124 	for (i = 0; i < n; i++)
125 		unpoison_page(page + i);
126 }
127 
__kernel_map_pages(struct page * page,int numpages,int enable)128 void __kernel_map_pages(struct page *page, int numpages, int enable)
129 {
130 	if (!page_poisoning_enabled)
131 		return;
132 
133 	if (enable)
134 		unpoison_pages(page, numpages);
135 	else
136 		poison_pages(page, numpages);
137 }
138