| #ifndef LINUX_KMEMCHECK_H | |
| #define LINUX_KMEMCHECK_H | |
| #include <linux/mm_types.h> | |
| #include <linux/types.h> | |
| #ifdef CONFIG_KMEMCHECK | |
| extern int kmemcheck_enabled; | |
| /* The slab-related functions. */ | |
| void kmemcheck_alloc_shadow(struct page *page, int order, gfp_t flags, int node); | |
| void kmemcheck_free_shadow(struct page *page, int order); | |
| void kmemcheck_slab_alloc(struct kmem_cache *s, gfp_t gfpflags, void *object, | |
| size_t size); | |
| void kmemcheck_slab_free(struct kmem_cache *s, void *object, size_t size); | |
| void kmemcheck_pagealloc_alloc(struct page *p, unsigned int order, | |
| gfp_t gfpflags); | |
| void kmemcheck_show_pages(struct page *p, unsigned int n); | |
| void kmemcheck_hide_pages(struct page *p, unsigned int n); | |
| bool kmemcheck_page_is_tracked(struct page *p); | |
| void kmemcheck_mark_unallocated(void *address, unsigned int n); | |
| void kmemcheck_mark_uninitialized(void *address, unsigned int n); | |
| void kmemcheck_mark_initialized(void *address, unsigned int n); | |
| void kmemcheck_mark_freed(void *address, unsigned int n); | |
| void kmemcheck_mark_unallocated_pages(struct page *p, unsigned int n); | |
| void kmemcheck_mark_uninitialized_pages(struct page *p, unsigned int n); | |
| void kmemcheck_mark_initialized_pages(struct page *p, unsigned int n); | |
| int kmemcheck_show_addr(unsigned long address); | |
| int kmemcheck_hide_addr(unsigned long address); | |
| bool kmemcheck_is_obj_initialized(unsigned long addr, size_t size); | |
| /* | |
| * 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); | |
| */ | |
| #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 { \ | |
| int _n; \ | |
| \ | |
| if (!ptr) \ | |
| break; \ | |
| \ | |
| _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) \ | |
| #else | |
| #define kmemcheck_enabled 0 | |
| static inline void | |
| kmemcheck_alloc_shadow(struct page *page, int order, gfp_t flags, int node) | |
| { | |
| } | |
| static inline void | |
| kmemcheck_free_shadow(struct page *page, int order) | |
| { | |
| } | |
| static inline void | |
| kmemcheck_slab_alloc(struct kmem_cache *s, gfp_t gfpflags, void *object, | |
| size_t size) | |
| { | |
| } | |
| static inline void kmemcheck_slab_free(struct kmem_cache *s, void *object, | |
| size_t size) | |
| { | |
| } | |
| static inline void kmemcheck_pagealloc_alloc(struct page *p, | |
| unsigned int order, gfp_t gfpflags) | |
| { | |
| } | |
| static inline bool kmemcheck_page_is_tracked(struct page *p) | |
| { | |
| return false; | |
| } | |
| static inline void kmemcheck_mark_unallocated(void *address, unsigned int n) | |
| { | |
| } | |
| static inline void kmemcheck_mark_uninitialized(void *address, unsigned int n) | |
| { | |
| } | |
| static inline void kmemcheck_mark_initialized(void *address, unsigned int n) | |
| { | |
| } | |
| static inline void kmemcheck_mark_freed(void *address, unsigned int n) | |
| { | |
| } | |
| static inline void kmemcheck_mark_unallocated_pages(struct page *p, | |
| unsigned int n) | |
| { | |
| } | |
| static inline void kmemcheck_mark_uninitialized_pages(struct page *p, | |
| unsigned int n) | |
| { | |
| } | |
| static inline void kmemcheck_mark_initialized_pages(struct page *p, | |
| unsigned int n) | |
| { | |
| } | |
| static inline bool kmemcheck_is_obj_initialized(unsigned long addr, size_t size) | |
| { | |
| return true; | |
| } | |
| #define kmemcheck_bitfield_begin(name) | |
| #define kmemcheck_bitfield_end(name) | |
| #define kmemcheck_annotate_bitfield(ptr, name) \ | |
| do { \ | |
| } while (0) | |
| #define kmemcheck_annotate_variable(var) \ | |
| do { \ | |
| } while (0) | |
| #endif /* CONFIG_KMEMCHECK */ | |
| #endif /* LINUX_KMEMCHECK_H */ |