debug-pagealloc.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. #include <linux/kernel.h>
  2. #include <linux/string.h>
  3. #include <linux/mm.h>
  4. #include <linux/highmem.h>
  5. #include <linux/page_ext.h>
  6. #include <linux/poison.h>
  7. #include <linux/ratelimit.h>
  8. static bool page_poisoning_enabled __read_mostly;
  9. static bool need_page_poisoning(void)
  10. {
  11. if (!debug_pagealloc_enabled())
  12. return false;
  13. return true;
  14. }
  15. static void init_page_poisoning(void)
  16. {
  17. if (!debug_pagealloc_enabled())
  18. return;
  19. page_poisoning_enabled = true;
  20. }
  21. struct page_ext_operations page_poisoning_ops = {
  22. .need = need_page_poisoning,
  23. .init = init_page_poisoning,
  24. };
  25. static inline void set_page_poison(struct page *page)
  26. {
  27. struct page_ext *page_ext;
  28. page_ext = lookup_page_ext(page);
  29. __set_bit(PAGE_EXT_DEBUG_POISON, &page_ext->flags);
  30. }
  31. static inline void clear_page_poison(struct page *page)
  32. {
  33. struct page_ext *page_ext;
  34. page_ext = lookup_page_ext(page);
  35. __clear_bit(PAGE_EXT_DEBUG_POISON, &page_ext->flags);
  36. }
  37. static inline bool page_poison(struct page *page)
  38. {
  39. struct page_ext *page_ext;
  40. page_ext = lookup_page_ext(page);
  41. return test_bit(PAGE_EXT_DEBUG_POISON, &page_ext->flags);
  42. }
  43. static void poison_page(struct page *page)
  44. {
  45. void *addr = kmap_atomic(page);
  46. set_page_poison(page);
  47. memset(addr, PAGE_POISON, PAGE_SIZE);
  48. kunmap_atomic(addr);
  49. }
  50. static void poison_pages(struct page *page, int n)
  51. {
  52. int i;
  53. for (i = 0; i < n; i++)
  54. poison_page(page + i);
  55. }
  56. static bool single_bit_flip(unsigned char a, unsigned char b)
  57. {
  58. unsigned char error = a ^ b;
  59. return error && !(error & (error - 1));
  60. }
  61. static void check_poison_mem(unsigned char *mem, size_t bytes)
  62. {
  63. static DEFINE_RATELIMIT_STATE(ratelimit, 5 * HZ, 10);
  64. unsigned char *start;
  65. unsigned char *end;
  66. start = memchr_inv(mem, PAGE_POISON, bytes);
  67. if (!start)
  68. return;
  69. for (end = mem + bytes - 1; end > start; end--) {
  70. if (*end != PAGE_POISON)
  71. break;
  72. }
  73. if (!__ratelimit(&ratelimit))
  74. return;
  75. else if (start == end && single_bit_flip(*start, PAGE_POISON))
  76. printk(KERN_ERR "pagealloc: single bit error\n");
  77. else
  78. printk(KERN_ERR "pagealloc: memory corruption\n");
  79. print_hex_dump(KERN_ERR, "", DUMP_PREFIX_ADDRESS, 16, 1, start,
  80. end - start + 1, 1);
  81. dump_stack();
  82. }
  83. static void unpoison_page(struct page *page)
  84. {
  85. void *addr;
  86. if (!page_poison(page))
  87. return;
  88. addr = kmap_atomic(page);
  89. check_poison_mem(addr, PAGE_SIZE);
  90. clear_page_poison(page);
  91. kunmap_atomic(addr);
  92. }
  93. static void unpoison_pages(struct page *page, int n)
  94. {
  95. int i;
  96. for (i = 0; i < n; i++)
  97. unpoison_page(page + i);
  98. }
  99. void __kernel_map_pages(struct page *page, int numpages, int enable)
  100. {
  101. if (!page_poisoning_enabled)
  102. return;
  103. if (enable)
  104. unpoison_pages(page, numpages);
  105. else
  106. poison_pages(page, numpages);
  107. }