blob: 39f8453239f779edcd0e5dedfc2d293b34bf7b60 [file] [log] [blame]
Vegard Nossumdfec0722008-04-04 00:51:41 +02001#ifndef LINUX_KMEMCHECK_H
2#define LINUX_KMEMCHECK_H
3
4#include <linux/mm_types.h>
5#include <linux/types.h>
6
7#ifdef CONFIG_KMEMCHECK
8extern int kmemcheck_enabled;
9
Vegard Nossum2dff4402008-05-31 15:56:17 +020010/* The slab-related functions. */
Vegard Nossumb1eeab62008-11-25 16:55:53 +010011void kmemcheck_alloc_shadow(struct page *page, int order, gfp_t flags, int node);
12void kmemcheck_free_shadow(struct page *page, int order);
Vegard Nossum2dff4402008-05-31 15:56:17 +020013void kmemcheck_slab_alloc(struct kmem_cache *s, gfp_t gfpflags, void *object,
14 size_t size);
15void kmemcheck_slab_free(struct kmem_cache *s, void *object, size_t size);
16
Vegard Nossumb1eeab62008-11-25 16:55:53 +010017void kmemcheck_pagealloc_alloc(struct page *p, unsigned int order,
18 gfp_t gfpflags);
19
Vegard Nossum2dff4402008-05-31 15:56:17 +020020void kmemcheck_show_pages(struct page *p, unsigned int n);
21void kmemcheck_hide_pages(struct page *p, unsigned int n);
22
23bool kmemcheck_page_is_tracked(struct page *p);
24
25void kmemcheck_mark_unallocated(void *address, unsigned int n);
26void kmemcheck_mark_uninitialized(void *address, unsigned int n);
27void kmemcheck_mark_initialized(void *address, unsigned int n);
28void kmemcheck_mark_freed(void *address, unsigned int n);
29
30void kmemcheck_mark_unallocated_pages(struct page *p, unsigned int n);
31void kmemcheck_mark_uninitialized_pages(struct page *p, unsigned int n);
Vegard Nossumb1eeab62008-11-25 16:55:53 +010032void kmemcheck_mark_initialized_pages(struct page *p, unsigned int n);
Vegard Nossum2dff4402008-05-31 15:56:17 +020033
Vegard Nossumdfec0722008-04-04 00:51:41 +020034int kmemcheck_show_addr(unsigned long address);
35int kmemcheck_hide_addr(unsigned long address);
Vegard Nossumfc7d0c92008-08-30 12:16:05 +020036
Pekka Enberg8e019362009-08-27 14:50:00 +010037bool kmemcheck_is_obj_initialized(unsigned long addr, size_t size);
38
Vegard Nossume992cd92010-01-08 14:42:35 -080039/*
40 * Bitfield annotations
41 *
42 * How to use: If you have a struct using bitfields, for example
43 *
44 * struct a {
45 * int x:8, y:8;
46 * };
47 *
48 * then this should be rewritten as
49 *
50 * struct a {
51 * kmemcheck_bitfield_begin(flags);
52 * int x:8, y:8;
53 * kmemcheck_bitfield_end(flags);
54 * };
55 *
56 * Now the "flags_begin" and "flags_end" members may be used to refer to the
57 * beginning and end, respectively, of the bitfield (and things like
58 * &x.flags_begin is allowed). As soon as the struct is allocated, the bit-
59 * fields should be annotated:
60 *
61 * struct a *a = kmalloc(sizeof(struct a), GFP_KERNEL);
62 * kmemcheck_annotate_bitfield(a, flags);
63 */
64#define kmemcheck_bitfield_begin(name) \
65 int name##_begin[0];
66
67#define kmemcheck_bitfield_end(name) \
68 int name##_end[0];
69
70#define kmemcheck_annotate_bitfield(ptr, name) \
71 do { \
72 int _n; \
73 \
74 if (!ptr) \
75 break; \
76 \
77 _n = (long) &((ptr)->name##_end) \
78 - (long) &((ptr)->name##_begin); \
Rusty Russell1765e3a2011-01-24 14:45:10 -060079 BUILD_BUG_ON(_n < 0); \
Vegard Nossume992cd92010-01-08 14:42:35 -080080 \
81 kmemcheck_mark_initialized(&((ptr)->name##_begin), _n); \
82 } while (0)
83
84#define kmemcheck_annotate_variable(var) \
85 do { \
86 kmemcheck_mark_initialized(&(var), sizeof(var)); \
87 } while (0) \
88
Vegard Nossumdfec0722008-04-04 00:51:41 +020089#else
90#define kmemcheck_enabled 0
91
Vegard Nossum2dff4402008-05-31 15:56:17 +020092static inline void
Vegard Nossumb1eeab62008-11-25 16:55:53 +010093kmemcheck_alloc_shadow(struct page *page, int order, gfp_t flags, int node)
Vegard Nossum2dff4402008-05-31 15:56:17 +020094{
95}
96
97static inline void
Vegard Nossumb1eeab62008-11-25 16:55:53 +010098kmemcheck_free_shadow(struct page *page, int order)
Vegard Nossum2dff4402008-05-31 15:56:17 +020099{
100}
101
102static inline void
103kmemcheck_slab_alloc(struct kmem_cache *s, gfp_t gfpflags, void *object,
104 size_t size)
105{
106}
107
108static inline void kmemcheck_slab_free(struct kmem_cache *s, void *object,
109 size_t size)
110{
111}
112
Vegard Nossumb1eeab62008-11-25 16:55:53 +0100113static inline void kmemcheck_pagealloc_alloc(struct page *p,
114 unsigned int order, gfp_t gfpflags)
115{
116}
117
Vegard Nossum2dff4402008-05-31 15:56:17 +0200118static inline bool kmemcheck_page_is_tracked(struct page *p)
119{
120 return false;
121}
Vegard Nossumd7002852008-07-20 10:44:54 +0200122
123static inline void kmemcheck_mark_unallocated(void *address, unsigned int n)
124{
125}
126
127static inline void kmemcheck_mark_uninitialized(void *address, unsigned int n)
128{
129}
130
131static inline void kmemcheck_mark_initialized(void *address, unsigned int n)
132{
133}
134
135static inline void kmemcheck_mark_freed(void *address, unsigned int n)
136{
137}
Vegard Nossumb1eeab62008-11-25 16:55:53 +0100138
139static inline void kmemcheck_mark_unallocated_pages(struct page *p,
140 unsigned int n)
141{
142}
143
144static inline void kmemcheck_mark_uninitialized_pages(struct page *p,
145 unsigned int n)
146{
147}
148
149static inline void kmemcheck_mark_initialized_pages(struct page *p,
150 unsigned int n)
151{
152}
153
Pekka Enberg8e019362009-08-27 14:50:00 +0100154static inline bool kmemcheck_is_obj_initialized(unsigned long addr, size_t size)
155{
156 return true;
157}
158
Vegard Nossume992cd92010-01-08 14:42:35 -0800159#define kmemcheck_bitfield_begin(name)
160#define kmemcheck_bitfield_end(name)
161#define kmemcheck_annotate_bitfield(ptr, name) \
162 do { \
Vegard Nossumfc7d0c92008-08-30 12:16:05 +0200163 } while (0)
164
Vegard Nossume992cd92010-01-08 14:42:35 -0800165#define kmemcheck_annotate_variable(var) \
166 do { \
167 } while (0)
168
169#endif /* CONFIG_KMEMCHECK */
Vegard Nossumfc7d0c92008-08-30 12:16:05 +0200170
Vegard Nossumdfec0722008-04-04 00:51:41 +0200171#endif /* LINUX_KMEMCHECK_H */