Root/
Source at commit ec7cab4cbb721bff91ec924ec691efd8daf36579 created 12 years 8 months ago. By Maarten ter Huurne, MIPS: JZ4740: A320: Updated quickstart documentation. | |
---|---|
1 | #include <linux/kernel.h> |
2 | #include <linux/mm.h> |
3 | #include <linux/page-debug-flags.h> |
4 | #include <linux/poison.h> |
5 | |
6 | static inline void set_page_poison(struct page *page) |
7 | { |
8 | __set_bit(PAGE_DEBUG_FLAG_POISON, &page->debug_flags); |
9 | } |
10 | |
11 | static inline void clear_page_poison(struct page *page) |
12 | { |
13 | __clear_bit(PAGE_DEBUG_FLAG_POISON, &page->debug_flags); |
14 | } |
15 | |
16 | static inline bool page_poison(struct page *page) |
17 | { |
18 | return test_bit(PAGE_DEBUG_FLAG_POISON, &page->debug_flags); |
19 | } |
20 | |
21 | static void poison_highpage(struct page *page) |
22 | { |
23 | /* |
24 | * Page poisoning for highmem pages is not implemented. |
25 | * |
26 | * This can be called from interrupt contexts. |
27 | * So we need to create a new kmap_atomic slot for this |
28 | * application and it will need interrupt protection. |
29 | */ |
30 | } |
31 | |
32 | static void poison_page(struct page *page) |
33 | { |
34 | void *addr; |
35 | |
36 | if (PageHighMem(page)) { |
37 | poison_highpage(page); |
38 | return; |
39 | } |
40 | set_page_poison(page); |
41 | addr = page_address(page); |
42 | memset(addr, PAGE_POISON, PAGE_SIZE); |
43 | } |
44 | |
45 | static void poison_pages(struct page *page, int n) |
46 | { |
47 | int i; |
48 | |
49 | for (i = 0; i < n; i++) |
50 | poison_page(page + i); |
51 | } |
52 | |
53 | static bool single_bit_flip(unsigned char a, unsigned char b) |
54 | { |
55 | unsigned char error = a ^ b; |
56 | |
57 | return error && !(error & (error - 1)); |
58 | } |
59 | |
60 | static void check_poison_mem(unsigned char *mem, size_t bytes) |
61 | { |
62 | unsigned char *start; |
63 | unsigned char *end; |
64 | |
65 | for (start = mem; start < mem + bytes; start++) { |
66 | if (*start != PAGE_POISON) |
67 | break; |
68 | } |
69 | if (start == mem + bytes) |
70 | return; |
71 | |
72 | for (end = mem + bytes - 1; end > start; end--) { |
73 | if (*end != PAGE_POISON) |
74 | break; |
75 | } |
76 | |
77 | if (!printk_ratelimit()) |
78 | return; |
79 | else if (start == end && single_bit_flip(*start, PAGE_POISON)) |
80 | printk(KERN_ERR "pagealloc: single bit error\n"); |
81 | else |
82 | printk(KERN_ERR "pagealloc: memory corruption\n"); |
83 | |
84 | print_hex_dump(KERN_ERR, "", DUMP_PREFIX_ADDRESS, 16, 1, start, |
85 | end - start + 1, 1); |
86 | dump_stack(); |
87 | } |
88 | |
89 | static void unpoison_highpage(struct page *page) |
90 | { |
91 | /* |
92 | * See comment in poison_highpage(). |
93 | * Highmem pages should not be poisoned for now |
94 | */ |
95 | BUG_ON(page_poison(page)); |
96 | } |
97 | |
98 | static void unpoison_page(struct page *page) |
99 | { |
100 | if (PageHighMem(page)) { |
101 | unpoison_highpage(page); |
102 | return; |
103 | } |
104 | if (page_poison(page)) { |
105 | void *addr = page_address(page); |
106 | |
107 | check_poison_mem(addr, PAGE_SIZE); |
108 | clear_page_poison(page); |
109 | } |
110 | } |
111 | |
112 | static void unpoison_pages(struct page *page, int n) |
113 | { |
114 | int i; |
115 | |
116 | for (i = 0; i < n; i++) |
117 | unpoison_page(page + i); |
118 | } |
119 | |
120 | void kernel_map_pages(struct page *page, int numpages, int enable) |
121 | { |
122 | if (!debug_pagealloc_enabled) |
123 | return; |
124 | |
125 | if (enable) |
126 | unpoison_pages(page, numpages); |
127 | else |
128 | poison_pages(page, numpages); |
129 | } |
130 |
Branches:
ben-wpan
ben-wpan-stefan
javiroman/ks7010
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9