1 #include <linux/kmemcheck.h>
2 #include <linux/module.h>
4 #include <linux/module.h>
7 #include <asm/pgtable.h>
13 * Return the shadow address for the given address. Returns NULL if the
14 * address is not tracked.
16 * We need to be extremely careful not to follow any invalid pointers,
17 * because this function can be called for *any* possible address.
19 void *kmemcheck_shadow_lookup(unsigned long address)
24 if (!virt_addr_valid(address))
27 pte = kmemcheck_pte_lookup(address);
31 page = virt_to_page(address);
34 return page->shadow + (address & (PAGE_SIZE - 1));
37 static void mark_shadow(void *address, unsigned int n,
38 enum kmemcheck_shadow status)
40 unsigned long addr = (unsigned long) address;
41 unsigned long last_addr = addr + n - 1;
42 unsigned long page = addr & PAGE_MASK;
43 unsigned long last_page = last_addr & PAGE_MASK;
47 /* If the memory range crosses a page boundary, stop there. */
48 if (page == last_page)
51 first_n = page + PAGE_SIZE - addr;
53 shadow = kmemcheck_shadow_lookup(addr);
55 memset(shadow, status, first_n);
60 /* Do full-page memset()s. */
61 while (n >= PAGE_SIZE) {
62 shadow = kmemcheck_shadow_lookup(addr);
64 memset(shadow, status, PAGE_SIZE);
70 /* Do the remaining page, if any. */
72 shadow = kmemcheck_shadow_lookup(addr);
74 memset(shadow, status, n);
78 void kmemcheck_mark_unallocated(void *address, unsigned int n)
80 mark_shadow(address, n, KMEMCHECK_SHADOW_UNALLOCATED);
83 void kmemcheck_mark_uninitialized(void *address, unsigned int n)
85 mark_shadow(address, n, KMEMCHECK_SHADOW_UNINITIALIZED);
89 * Fill the shadow memory of the given address such that the memory at that
90 * address is marked as being initialized.
92 void kmemcheck_mark_initialized(void *address, unsigned int n)
94 mark_shadow(address, n, KMEMCHECK_SHADOW_INITIALIZED);
96 EXPORT_SYMBOL_GPL(kmemcheck_mark_initialized);
98 void kmemcheck_mark_freed(void *address, unsigned int n)
100 mark_shadow(address, n, KMEMCHECK_SHADOW_FREED);
103 void kmemcheck_mark_unallocated_pages(struct page *p, unsigned int n)
107 for (i = 0; i < n; ++i)
108 kmemcheck_mark_unallocated(page_address(&p[i]), PAGE_SIZE);
111 void kmemcheck_mark_uninitialized_pages(struct page *p, unsigned int n)
115 for (i = 0; i < n; ++i)
116 kmemcheck_mark_uninitialized(page_address(&p[i]), PAGE_SIZE);
119 void kmemcheck_mark_initialized_pages(struct page *p, unsigned int n)
123 for (i = 0; i < n; ++i)
124 kmemcheck_mark_initialized(page_address(&p[i]), PAGE_SIZE);
127 enum kmemcheck_shadow kmemcheck_shadow_test(void *shadow, unsigned int size)
134 #ifdef CONFIG_KMEMCHECK_PARTIAL_OK
136 * Make sure _some_ bytes are initialized. Gcc frequently generates
137 * code to access neighboring bytes.
139 for (i = 0; i < size; ++i) {
140 if (x[i] == KMEMCHECK_SHADOW_INITIALIZED)
144 /* All bytes must be initialized. */
145 for (i = 0; i < size; ++i) {
146 if (x[i] != KMEMCHECK_SHADOW_INITIALIZED)
154 void kmemcheck_shadow_set(void *shadow, unsigned int size)
160 for (i = 0; i < size; ++i)
161 x[i] = KMEMCHECK_SHADOW_INITIALIZED;