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>
This commit is contained in:
parent
ac61a75796
commit
fc7d0c9f21
|
@ -33,6 +33,7 @@ void kmemcheck_mark_initialized_pages(struct page *p, unsigned int n);
|
||||||
|
|
||||||
int kmemcheck_show_addr(unsigned long address);
|
int kmemcheck_show_addr(unsigned long address);
|
||||||
int kmemcheck_hide_addr(unsigned long address);
|
int kmemcheck_hide_addr(unsigned long address);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#define kmemcheck_enabled 0
|
#define kmemcheck_enabled 0
|
||||||
|
|
||||||
|
@ -100,4 +101,53 @@ static inline void kmemcheck_mark_initialized_pages(struct page *p,
|
||||||
|
|
||||||
#endif /* CONFIG_KMEMCHECK */
|
#endif /* CONFIG_KMEMCHECK */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bitfield annotations
|
||||||
|
*
|
||||||
|
* How to use: If you have a struct using bitfields, for example
|
||||||
|
*
|
||||||
|
* struct a {
|
||||||
|
* int x:8, y:8;
|
||||||
|
* };
|
||||||
|
*
|
||||||
|
* then this should be rewritten as
|
||||||
|
*
|
||||||
|
* struct a {
|
||||||
|
* kmemcheck_bitfield_begin(flags);
|
||||||
|
* int x:8, y:8;
|
||||||
|
* kmemcheck_bitfield_end(flags);
|
||||||
|
* };
|
||||||
|
*
|
||||||
|
* Now the "flags_begin" and "flags_end" members may be used to refer to the
|
||||||
|
* beginning and end, respectively, of the bitfield (and things like
|
||||||
|
* &x.flags_begin is allowed). As soon as the struct is allocated, the bit-
|
||||||
|
* fields should be annotated:
|
||||||
|
*
|
||||||
|
* struct a *a = kmalloc(sizeof(struct a), GFP_KERNEL);
|
||||||
|
* kmemcheck_annotate_bitfield(a, flags);
|
||||||
|
*
|
||||||
|
* Note: We provide the same definitions for both kmemcheck and non-
|
||||||
|
* kmemcheck kernels. This makes it harder to introduce accidental errors. It
|
||||||
|
* is also allowed to pass NULL pointers to kmemcheck_annotate_bitfield().
|
||||||
|
*/
|
||||||
|
#define kmemcheck_bitfield_begin(name) \
|
||||||
|
int name##_begin[0];
|
||||||
|
|
||||||
|
#define kmemcheck_bitfield_end(name) \
|
||||||
|
int name##_end[0];
|
||||||
|
|
||||||
|
#define kmemcheck_annotate_bitfield(ptr, name) \
|
||||||
|
do if (ptr) { \
|
||||||
|
int _n = (long) &((ptr)->name##_end) \
|
||||||
|
- (long) &((ptr)->name##_begin); \
|
||||||
|
BUILD_BUG_ON(_n < 0); \
|
||||||
|
\
|
||||||
|
kmemcheck_mark_initialized(&((ptr)->name##_begin), _n); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define kmemcheck_annotate_variable(var) \
|
||||||
|
do { \
|
||||||
|
kmemcheck_mark_initialized(&(var), sizeof(var)); \
|
||||||
|
} while (0) \
|
||||||
|
|
||||||
#endif /* LINUX_KMEMCHECK_H */
|
#endif /* LINUX_KMEMCHECK_H */
|
||||||
|
|
Loading…
Reference in New Issue