instrumented-non-atomic.h 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. /*
  3. * This file provides wrappers with sanitizer instrumentation for non-atomic
  4. * bit operations.
  5. *
  6. * To use this functionality, an arch's bitops.h file needs to define each of
  7. * the below bit operations with an arch_ prefix (e.g. arch_set_bit(),
  8. * arch___set_bit(), etc.).
  9. */
  10. #ifndef _ASM_GENERIC_BITOPS_INSTRUMENTED_NON_ATOMIC_H
  11. #define _ASM_GENERIC_BITOPS_INSTRUMENTED_NON_ATOMIC_H
  12. #include <linux/instrumented.h>
  13. /**
  14. * ___set_bit - Set a bit in memory
  15. * @nr: the bit to set
  16. * @addr: the address to start counting from
  17. *
  18. * Unlike set_bit(), this function is non-atomic. If it is called on the same
  19. * region of memory concurrently, the effect may be that only one operation
  20. * succeeds.
  21. */
  22. static __always_inline void
  23. ___set_bit(unsigned long nr, volatile unsigned long *addr)
  24. {
  25. instrument_write(addr + BIT_WORD(nr), sizeof(long));
  26. arch___set_bit(nr, addr);
  27. }
  28. /**
  29. * ___clear_bit - Clears a bit in memory
  30. * @nr: the bit to clear
  31. * @addr: the address to start counting from
  32. *
  33. * Unlike clear_bit(), this function is non-atomic. If it is called on the same
  34. * region of memory concurrently, the effect may be that only one operation
  35. * succeeds.
  36. */
  37. static __always_inline void
  38. ___clear_bit(unsigned long nr, volatile unsigned long *addr)
  39. {
  40. instrument_write(addr + BIT_WORD(nr), sizeof(long));
  41. arch___clear_bit(nr, addr);
  42. }
  43. /**
  44. * ___change_bit - Toggle a bit in memory
  45. * @nr: the bit to change
  46. * @addr: the address to start counting from
  47. *
  48. * Unlike change_bit(), this function is non-atomic. If it is called on the same
  49. * region of memory concurrently, the effect may be that only one operation
  50. * succeeds.
  51. */
  52. static __always_inline void
  53. ___change_bit(unsigned long nr, volatile unsigned long *addr)
  54. {
  55. instrument_write(addr + BIT_WORD(nr), sizeof(long));
  56. arch___change_bit(nr, addr);
  57. }
  58. static __always_inline void __instrument_read_write_bitop(long nr, volatile unsigned long *addr)
  59. {
  60. if (IS_ENABLED(CONFIG_KCSAN_ASSUME_PLAIN_WRITES_ATOMIC)) {
  61. /*
  62. * We treat non-atomic read-write bitops a little more special.
  63. * Given the operations here only modify a single bit, assuming
  64. * non-atomicity of the writer is sufficient may be reasonable
  65. * for certain usage (and follows the permissible nature of the
  66. * assume-plain-writes-atomic rule):
  67. * 1. report read-modify-write races -> check read;
  68. * 2. do not report races with marked readers, but do report
  69. * races with unmarked readers -> check "atomic" write.
  70. */
  71. kcsan_check_read(addr + BIT_WORD(nr), sizeof(long));
  72. /*
  73. * Use generic write instrumentation, in case other sanitizers
  74. * or tools are enabled alongside KCSAN.
  75. */
  76. instrument_write(addr + BIT_WORD(nr), sizeof(long));
  77. } else {
  78. instrument_read_write(addr + BIT_WORD(nr), sizeof(long));
  79. }
  80. }
  81. /**
  82. * ___test_and_set_bit - Set a bit and return its old value
  83. * @nr: Bit to set
  84. * @addr: Address to count from
  85. *
  86. * This operation is non-atomic. If two instances of this operation race, one
  87. * can appear to succeed but actually fail.
  88. */
  89. static __always_inline bool
  90. ___test_and_set_bit(unsigned long nr, volatile unsigned long *addr)
  91. {
  92. __instrument_read_write_bitop(nr, addr);
  93. return arch___test_and_set_bit(nr, addr);
  94. }
  95. /**
  96. * ___test_and_clear_bit - Clear a bit and return its old value
  97. * @nr: Bit to clear
  98. * @addr: Address to count from
  99. *
  100. * This operation is non-atomic. If two instances of this operation race, one
  101. * can appear to succeed but actually fail.
  102. */
  103. static __always_inline bool
  104. ___test_and_clear_bit(unsigned long nr, volatile unsigned long *addr)
  105. {
  106. __instrument_read_write_bitop(nr, addr);
  107. return arch___test_and_clear_bit(nr, addr);
  108. }
  109. /**
  110. * ___test_and_change_bit - Change a bit and return its old value
  111. * @nr: Bit to change
  112. * @addr: Address to count from
  113. *
  114. * This operation is non-atomic. If two instances of this operation race, one
  115. * can appear to succeed but actually fail.
  116. */
  117. static __always_inline bool
  118. ___test_and_change_bit(unsigned long nr, volatile unsigned long *addr)
  119. {
  120. __instrument_read_write_bitop(nr, addr);
  121. return arch___test_and_change_bit(nr, addr);
  122. }
  123. /**
  124. * _test_bit - Determine whether a bit is set
  125. * @nr: bit number to test
  126. * @addr: Address to start counting from
  127. */
  128. static __always_inline bool
  129. _test_bit(unsigned long nr, const volatile unsigned long *addr)
  130. {
  131. instrument_atomic_read(addr + BIT_WORD(nr), sizeof(long));
  132. return arch_test_bit(nr, addr);
  133. }
  134. /**
  135. * _test_bit_acquire - Determine, with acquire semantics, whether a bit is set
  136. * @nr: bit number to test
  137. * @addr: Address to start counting from
  138. */
  139. static __always_inline bool
  140. _test_bit_acquire(unsigned long nr, const volatile unsigned long *addr)
  141. {
  142. instrument_atomic_read(addr + BIT_WORD(nr), sizeof(long));
  143. return arch_test_bit_acquire(nr, addr);
  144. }
  145. #endif /* _ASM_GENERIC_BITOPS_INSTRUMENTED_NON_ATOMIC_H */