1dfec072ecd35ba6ecad2d51dde325253ac9a2936Vegard Nossum#ifndef LINUX_KMEMCHECK_H
2dfec072ecd35ba6ecad2d51dde325253ac9a2936Vegard Nossum#define LINUX_KMEMCHECK_H
3dfec072ecd35ba6ecad2d51dde325253ac9a2936Vegard Nossum
4dfec072ecd35ba6ecad2d51dde325253ac9a2936Vegard Nossum#include <linux/mm_types.h>
5dfec072ecd35ba6ecad2d51dde325253ac9a2936Vegard Nossum#include <linux/types.h>
6dfec072ecd35ba6ecad2d51dde325253ac9a2936Vegard Nossum
7dfec072ecd35ba6ecad2d51dde325253ac9a2936Vegard Nossum#ifdef CONFIG_KMEMCHECK
8dfec072ecd35ba6ecad2d51dde325253ac9a2936Vegard Nossumextern int kmemcheck_enabled;
9dfec072ecd35ba6ecad2d51dde325253ac9a2936Vegard Nossum
102dff440525f8faba8836e9f05297b76f23b4af30Vegard Nossum/* The slab-related functions. */
11b1eeab67682a5e397aecf172046b3a8bd4808ae4Vegard Nossumvoid kmemcheck_alloc_shadow(struct page *page, int order, gfp_t flags, int node);
12b1eeab67682a5e397aecf172046b3a8bd4808ae4Vegard Nossumvoid kmemcheck_free_shadow(struct page *page, int order);
132dff440525f8faba8836e9f05297b76f23b4af30Vegard Nossumvoid kmemcheck_slab_alloc(struct kmem_cache *s, gfp_t gfpflags, void *object,
142dff440525f8faba8836e9f05297b76f23b4af30Vegard Nossum			  size_t size);
152dff440525f8faba8836e9f05297b76f23b4af30Vegard Nossumvoid kmemcheck_slab_free(struct kmem_cache *s, void *object, size_t size);
162dff440525f8faba8836e9f05297b76f23b4af30Vegard Nossum
17b1eeab67682a5e397aecf172046b3a8bd4808ae4Vegard Nossumvoid kmemcheck_pagealloc_alloc(struct page *p, unsigned int order,
18b1eeab67682a5e397aecf172046b3a8bd4808ae4Vegard Nossum			       gfp_t gfpflags);
19b1eeab67682a5e397aecf172046b3a8bd4808ae4Vegard Nossum
202dff440525f8faba8836e9f05297b76f23b4af30Vegard Nossumvoid kmemcheck_show_pages(struct page *p, unsigned int n);
212dff440525f8faba8836e9f05297b76f23b4af30Vegard Nossumvoid kmemcheck_hide_pages(struct page *p, unsigned int n);
222dff440525f8faba8836e9f05297b76f23b4af30Vegard Nossum
232dff440525f8faba8836e9f05297b76f23b4af30Vegard Nossumbool kmemcheck_page_is_tracked(struct page *p);
242dff440525f8faba8836e9f05297b76f23b4af30Vegard Nossum
252dff440525f8faba8836e9f05297b76f23b4af30Vegard Nossumvoid kmemcheck_mark_unallocated(void *address, unsigned int n);
262dff440525f8faba8836e9f05297b76f23b4af30Vegard Nossumvoid kmemcheck_mark_uninitialized(void *address, unsigned int n);
272dff440525f8faba8836e9f05297b76f23b4af30Vegard Nossumvoid kmemcheck_mark_initialized(void *address, unsigned int n);
282dff440525f8faba8836e9f05297b76f23b4af30Vegard Nossumvoid kmemcheck_mark_freed(void *address, unsigned int n);
292dff440525f8faba8836e9f05297b76f23b4af30Vegard Nossum
302dff440525f8faba8836e9f05297b76f23b4af30Vegard Nossumvoid kmemcheck_mark_unallocated_pages(struct page *p, unsigned int n);
312dff440525f8faba8836e9f05297b76f23b4af30Vegard Nossumvoid kmemcheck_mark_uninitialized_pages(struct page *p, unsigned int n);
32b1eeab67682a5e397aecf172046b3a8bd4808ae4Vegard Nossumvoid kmemcheck_mark_initialized_pages(struct page *p, unsigned int n);
332dff440525f8faba8836e9f05297b76f23b4af30Vegard Nossum
34dfec072ecd35ba6ecad2d51dde325253ac9a2936Vegard Nossumint kmemcheck_show_addr(unsigned long address);
35dfec072ecd35ba6ecad2d51dde325253ac9a2936Vegard Nossumint kmemcheck_hide_addr(unsigned long address);
36fc7d0c9f2122e8bf58deaf1252b0e750df5b0e91Vegard Nossum
378e019366ba749a536131cde1947af6dcaccf8e8fPekka Enbergbool kmemcheck_is_obj_initialized(unsigned long addr, size_t size);
388e019366ba749a536131cde1947af6dcaccf8e8fPekka Enberg
39e992cd9b72a18122bd5c958715623057f110793fVegard Nossum/*
40e992cd9b72a18122bd5c958715623057f110793fVegard Nossum * Bitfield annotations
41e992cd9b72a18122bd5c958715623057f110793fVegard Nossum *
42e992cd9b72a18122bd5c958715623057f110793fVegard Nossum * How to use: If you have a struct using bitfields, for example
43e992cd9b72a18122bd5c958715623057f110793fVegard Nossum *
44e992cd9b72a18122bd5c958715623057f110793fVegard Nossum *     struct a {
45e992cd9b72a18122bd5c958715623057f110793fVegard Nossum *             int x:8, y:8;
46e992cd9b72a18122bd5c958715623057f110793fVegard Nossum *     };
47e992cd9b72a18122bd5c958715623057f110793fVegard Nossum *
48e992cd9b72a18122bd5c958715623057f110793fVegard Nossum * then this should be rewritten as
49e992cd9b72a18122bd5c958715623057f110793fVegard Nossum *
50e992cd9b72a18122bd5c958715623057f110793fVegard Nossum *     struct a {
51e992cd9b72a18122bd5c958715623057f110793fVegard Nossum *             kmemcheck_bitfield_begin(flags);
52e992cd9b72a18122bd5c958715623057f110793fVegard Nossum *             int x:8, y:8;
53e992cd9b72a18122bd5c958715623057f110793fVegard Nossum *             kmemcheck_bitfield_end(flags);
54e992cd9b72a18122bd5c958715623057f110793fVegard Nossum *     };
55e992cd9b72a18122bd5c958715623057f110793fVegard Nossum *
56e992cd9b72a18122bd5c958715623057f110793fVegard Nossum * Now the "flags_begin" and "flags_end" members may be used to refer to the
57e992cd9b72a18122bd5c958715623057f110793fVegard Nossum * beginning and end, respectively, of the bitfield (and things like
58e992cd9b72a18122bd5c958715623057f110793fVegard Nossum * &x.flags_begin is allowed). As soon as the struct is allocated, the bit-
59e992cd9b72a18122bd5c958715623057f110793fVegard Nossum * fields should be annotated:
60e992cd9b72a18122bd5c958715623057f110793fVegard Nossum *
61e992cd9b72a18122bd5c958715623057f110793fVegard Nossum *     struct a *a = kmalloc(sizeof(struct a), GFP_KERNEL);
62e992cd9b72a18122bd5c958715623057f110793fVegard Nossum *     kmemcheck_annotate_bitfield(a, flags);
63e992cd9b72a18122bd5c958715623057f110793fVegard Nossum */
64e992cd9b72a18122bd5c958715623057f110793fVegard Nossum#define kmemcheck_bitfield_begin(name)	\
65e992cd9b72a18122bd5c958715623057f110793fVegard Nossum	int name##_begin[0];
66e992cd9b72a18122bd5c958715623057f110793fVegard Nossum
67e992cd9b72a18122bd5c958715623057f110793fVegard Nossum#define kmemcheck_bitfield_end(name)	\
68e992cd9b72a18122bd5c958715623057f110793fVegard Nossum	int name##_end[0];
69e992cd9b72a18122bd5c958715623057f110793fVegard Nossum
70e992cd9b72a18122bd5c958715623057f110793fVegard Nossum#define kmemcheck_annotate_bitfield(ptr, name)				\
71e992cd9b72a18122bd5c958715623057f110793fVegard Nossum	do {								\
72e992cd9b72a18122bd5c958715623057f110793fVegard Nossum		int _n;							\
73e992cd9b72a18122bd5c958715623057f110793fVegard Nossum									\
74e992cd9b72a18122bd5c958715623057f110793fVegard Nossum		if (!ptr)						\
75e992cd9b72a18122bd5c958715623057f110793fVegard Nossum			break;						\
76e992cd9b72a18122bd5c958715623057f110793fVegard Nossum									\
77e992cd9b72a18122bd5c958715623057f110793fVegard Nossum		_n = (long) &((ptr)->name##_end)			\
78e992cd9b72a18122bd5c958715623057f110793fVegard Nossum			- (long) &((ptr)->name##_begin);		\
791765e3a4933ea0870fabd755feffc5473c4363ceRusty Russell		BUILD_BUG_ON(_n < 0);					\
80e992cd9b72a18122bd5c958715623057f110793fVegard Nossum									\
81e992cd9b72a18122bd5c958715623057f110793fVegard Nossum		kmemcheck_mark_initialized(&((ptr)->name##_begin), _n);	\
82e992cd9b72a18122bd5c958715623057f110793fVegard Nossum	} while (0)
83e992cd9b72a18122bd5c958715623057f110793fVegard Nossum
84e992cd9b72a18122bd5c958715623057f110793fVegard Nossum#define kmemcheck_annotate_variable(var)				\
85e992cd9b72a18122bd5c958715623057f110793fVegard Nossum	do {								\
86e992cd9b72a18122bd5c958715623057f110793fVegard Nossum		kmemcheck_mark_initialized(&(var), sizeof(var));	\
87e992cd9b72a18122bd5c958715623057f110793fVegard Nossum	} while (0)							\
88e992cd9b72a18122bd5c958715623057f110793fVegard Nossum
89dfec072ecd35ba6ecad2d51dde325253ac9a2936Vegard Nossum#else
90dfec072ecd35ba6ecad2d51dde325253ac9a2936Vegard Nossum#define kmemcheck_enabled 0
91dfec072ecd35ba6ecad2d51dde325253ac9a2936Vegard Nossum
922dff440525f8faba8836e9f05297b76f23b4af30Vegard Nossumstatic inline void
93b1eeab67682a5e397aecf172046b3a8bd4808ae4Vegard Nossumkmemcheck_alloc_shadow(struct page *page, int order, gfp_t flags, int node)
942dff440525f8faba8836e9f05297b76f23b4af30Vegard Nossum{
952dff440525f8faba8836e9f05297b76f23b4af30Vegard Nossum}
962dff440525f8faba8836e9f05297b76f23b4af30Vegard Nossum
972dff440525f8faba8836e9f05297b76f23b4af30Vegard Nossumstatic inline void
98b1eeab67682a5e397aecf172046b3a8bd4808ae4Vegard Nossumkmemcheck_free_shadow(struct page *page, int order)
992dff440525f8faba8836e9f05297b76f23b4af30Vegard Nossum{
1002dff440525f8faba8836e9f05297b76f23b4af30Vegard Nossum}
1012dff440525f8faba8836e9f05297b76f23b4af30Vegard Nossum
1022dff440525f8faba8836e9f05297b76f23b4af30Vegard Nossumstatic inline void
1032dff440525f8faba8836e9f05297b76f23b4af30Vegard Nossumkmemcheck_slab_alloc(struct kmem_cache *s, gfp_t gfpflags, void *object,
1042dff440525f8faba8836e9f05297b76f23b4af30Vegard Nossum		     size_t size)
1052dff440525f8faba8836e9f05297b76f23b4af30Vegard Nossum{
1062dff440525f8faba8836e9f05297b76f23b4af30Vegard Nossum}
1072dff440525f8faba8836e9f05297b76f23b4af30Vegard Nossum
1082dff440525f8faba8836e9f05297b76f23b4af30Vegard Nossumstatic inline void kmemcheck_slab_free(struct kmem_cache *s, void *object,
1092dff440525f8faba8836e9f05297b76f23b4af30Vegard Nossum				       size_t size)
1102dff440525f8faba8836e9f05297b76f23b4af30Vegard Nossum{
1112dff440525f8faba8836e9f05297b76f23b4af30Vegard Nossum}
1122dff440525f8faba8836e9f05297b76f23b4af30Vegard Nossum
113b1eeab67682a5e397aecf172046b3a8bd4808ae4Vegard Nossumstatic inline void kmemcheck_pagealloc_alloc(struct page *p,
114b1eeab67682a5e397aecf172046b3a8bd4808ae4Vegard Nossum	unsigned int order, gfp_t gfpflags)
115b1eeab67682a5e397aecf172046b3a8bd4808ae4Vegard Nossum{
116b1eeab67682a5e397aecf172046b3a8bd4808ae4Vegard Nossum}
117b1eeab67682a5e397aecf172046b3a8bd4808ae4Vegard Nossum
1182dff440525f8faba8836e9f05297b76f23b4af30Vegard Nossumstatic inline bool kmemcheck_page_is_tracked(struct page *p)
1192dff440525f8faba8836e9f05297b76f23b4af30Vegard Nossum{
1202dff440525f8faba8836e9f05297b76f23b4af30Vegard Nossum	return false;
1212dff440525f8faba8836e9f05297b76f23b4af30Vegard Nossum}
122d7002857dee6e9a3ce1f78d23f37caba106b29c5Vegard Nossum
123d7002857dee6e9a3ce1f78d23f37caba106b29c5Vegard Nossumstatic inline void kmemcheck_mark_unallocated(void *address, unsigned int n)
124d7002857dee6e9a3ce1f78d23f37caba106b29c5Vegard Nossum{
125d7002857dee6e9a3ce1f78d23f37caba106b29c5Vegard Nossum}
126d7002857dee6e9a3ce1f78d23f37caba106b29c5Vegard Nossum
127d7002857dee6e9a3ce1f78d23f37caba106b29c5Vegard Nossumstatic inline void kmemcheck_mark_uninitialized(void *address, unsigned int n)
128d7002857dee6e9a3ce1f78d23f37caba106b29c5Vegard Nossum{
129d7002857dee6e9a3ce1f78d23f37caba106b29c5Vegard Nossum}
130d7002857dee6e9a3ce1f78d23f37caba106b29c5Vegard Nossum
131d7002857dee6e9a3ce1f78d23f37caba106b29c5Vegard Nossumstatic inline void kmemcheck_mark_initialized(void *address, unsigned int n)
132d7002857dee6e9a3ce1f78d23f37caba106b29c5Vegard Nossum{
133d7002857dee6e9a3ce1f78d23f37caba106b29c5Vegard Nossum}
134d7002857dee6e9a3ce1f78d23f37caba106b29c5Vegard Nossum
135d7002857dee6e9a3ce1f78d23f37caba106b29c5Vegard Nossumstatic inline void kmemcheck_mark_freed(void *address, unsigned int n)
136d7002857dee6e9a3ce1f78d23f37caba106b29c5Vegard Nossum{
137d7002857dee6e9a3ce1f78d23f37caba106b29c5Vegard Nossum}
138b1eeab67682a5e397aecf172046b3a8bd4808ae4Vegard Nossum
139b1eeab67682a5e397aecf172046b3a8bd4808ae4Vegard Nossumstatic inline void kmemcheck_mark_unallocated_pages(struct page *p,
140b1eeab67682a5e397aecf172046b3a8bd4808ae4Vegard Nossum						    unsigned int n)
141b1eeab67682a5e397aecf172046b3a8bd4808ae4Vegard Nossum{
142b1eeab67682a5e397aecf172046b3a8bd4808ae4Vegard Nossum}
143b1eeab67682a5e397aecf172046b3a8bd4808ae4Vegard Nossum
144b1eeab67682a5e397aecf172046b3a8bd4808ae4Vegard Nossumstatic inline void kmemcheck_mark_uninitialized_pages(struct page *p,
145b1eeab67682a5e397aecf172046b3a8bd4808ae4Vegard Nossum						      unsigned int n)
146b1eeab67682a5e397aecf172046b3a8bd4808ae4Vegard Nossum{
147b1eeab67682a5e397aecf172046b3a8bd4808ae4Vegard Nossum}
148b1eeab67682a5e397aecf172046b3a8bd4808ae4Vegard Nossum
149b1eeab67682a5e397aecf172046b3a8bd4808ae4Vegard Nossumstatic inline void kmemcheck_mark_initialized_pages(struct page *p,
150b1eeab67682a5e397aecf172046b3a8bd4808ae4Vegard Nossum						    unsigned int n)
151b1eeab67682a5e397aecf172046b3a8bd4808ae4Vegard Nossum{
152b1eeab67682a5e397aecf172046b3a8bd4808ae4Vegard Nossum}
153b1eeab67682a5e397aecf172046b3a8bd4808ae4Vegard Nossum
1548e019366ba749a536131cde1947af6dcaccf8e8fPekka Enbergstatic inline bool kmemcheck_is_obj_initialized(unsigned long addr, size_t size)
1558e019366ba749a536131cde1947af6dcaccf8e8fPekka Enberg{
1568e019366ba749a536131cde1947af6dcaccf8e8fPekka Enberg	return true;
1578e019366ba749a536131cde1947af6dcaccf8e8fPekka Enberg}
1588e019366ba749a536131cde1947af6dcaccf8e8fPekka Enberg
159e992cd9b72a18122bd5c958715623057f110793fVegard Nossum#define kmemcheck_bitfield_begin(name)
160e992cd9b72a18122bd5c958715623057f110793fVegard Nossum#define kmemcheck_bitfield_end(name)
161e992cd9b72a18122bd5c958715623057f110793fVegard Nossum#define kmemcheck_annotate_bitfield(ptr, name)	\
162e992cd9b72a18122bd5c958715623057f110793fVegard Nossum	do {					\
163e992cd9b72a18122bd5c958715623057f110793fVegard Nossum	} while (0)
164fc7d0c9f2122e8bf58deaf1252b0e750df5b0e91Vegard Nossum
165e992cd9b72a18122bd5c958715623057f110793fVegard Nossum#define kmemcheck_annotate_variable(var)	\
166e992cd9b72a18122bd5c958715623057f110793fVegard Nossum	do {					\
167fc7d0c9f2122e8bf58deaf1252b0e750df5b0e91Vegard Nossum	} while (0)
168fc7d0c9f2122e8bf58deaf1252b0e750df5b0e91Vegard Nossum
169e992cd9b72a18122bd5c958715623057f110793fVegard Nossum#endif /* CONFIG_KMEMCHECK */
170fc7d0c9f2122e8bf58deaf1252b0e750df5b0e91Vegard Nossum
171dfec072ecd35ba6ecad2d51dde325253ac9a2936Vegard Nossum#endif /* LINUX_KMEMCHECK_H */
172