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