aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVegard Nossum <vegard.nossum@gmail.com>2008-08-30 06:16:05 -0400
committerVegard Nossum <vegard.nossum@gmail.com>2009-06-15 09:49:23 -0400
commitfc7d0c9f2122e8bf58deaf1252b0e750df5b0e91 (patch)
tree9279ca21566062038582682e59accccfa904054d
parentac61a7579625ddfca3b2e0aa298879a94d15884d (diff)
kmemcheck: introduce bitfield API
Add the bitfield API which can be used to annotate bitfields in structs and get rid of false positive reports. According to Al Viro, the syntax we were using (putting #ifdef inside macro arguments) was not valid C. He also suggested using begin/end markers instead, which is what we do now. [rebased for mainline inclusion] Signed-off-by: Vegard Nossum <vegard.nossum@gmail.com>
-rw-r--r--include/linux/kmemcheck.h50
1 files changed, 50 insertions, 0 deletions
diff --git a/include/linux/kmemcheck.h b/include/linux/kmemcheck.h
index 093d23969b1b..47b39b7c7e84 100644
--- a/include/linux/kmemcheck.h
+++ b/include/linux/kmemcheck.h
@@ -33,6 +33,7 @@ void kmemcheck_mark_initialized_pages(struct page *p, unsigned int n);
33 33
34int kmemcheck_show_addr(unsigned long address); 34int kmemcheck_show_addr(unsigned long address);
35int kmemcheck_hide_addr(unsigned long address); 35int kmemcheck_hide_addr(unsigned long address);
36
36#else 37#else
37#define kmemcheck_enabled 0 38#define kmemcheck_enabled 0
38 39
@@ -100,4 +101,53 @@ static inline void kmemcheck_mark_initialized_pages(struct page *p,
100 101
101#endif /* CONFIG_KMEMCHECK */ 102#endif /* CONFIG_KMEMCHECK */
102 103
104/*
105 * Bitfield annotations
106 *
107 * How to use: If you have a struct using bitfields, for example
108 *
109 * struct a {
110 * int x:8, y:8;
111 * };
112 *
113 * then this should be rewritten as
114 *
115 * struct a {
116 * kmemcheck_bitfield_begin(flags);
117 * int x:8, y:8;
118 * kmemcheck_bitfield_end(flags);
119 * };
120 *
121 * Now the "flags_begin" and "flags_end" members may be used to refer to the
122 * beginning and end, respectively, of the bitfield (and things like
123 * &x.flags_begin is allowed). As soon as the struct is allocated, the bit-
124 * fields should be annotated:
125 *
126 * struct a *a = kmalloc(sizeof(struct a), GFP_KERNEL);
127 * kmemcheck_annotate_bitfield(a, flags);
128 *
129 * Note: We provide the same definitions for both kmemcheck and non-
130 * kmemcheck kernels. This makes it harder to introduce accidental errors. It
131 * is also allowed to pass NULL pointers to kmemcheck_annotate_bitfield().
132 */
133#define kmemcheck_bitfield_begin(name) \
134 int name##_begin[0];
135
136#define kmemcheck_bitfield_end(name) \
137 int name##_end[0];
138
139#define kmemcheck_annotate_bitfield(ptr, name) \
140 do if (ptr) { \
141 int _n = (long) &((ptr)->name##_end) \
142 - (long) &((ptr)->name##_begin); \
143 BUILD_BUG_ON(_n < 0); \
144 \
145 kmemcheck_mark_initialized(&((ptr)->name##_begin), _n); \
146 } while (0)
147
148#define kmemcheck_annotate_variable(var) \
149 do { \
150 kmemcheck_mark_initialized(&(var), sizeof(var)); \
151 } while (0) \
152
103#endif /* LINUX_KMEMCHECK_H */ 153#endif /* LINUX_KMEMCHECK_H */