^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * This file provides wrappers with sanitizer instrumentation for atomic bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * operations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * To use this functionality, an arch's bitops.h file needs to define each of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * the below bit operations with an arch_ prefix (e.g. arch_set_bit(),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * arch___set_bit(), etc.).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #ifndef _ASM_GENERIC_BITOPS_INSTRUMENTED_ATOMIC_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #define _ASM_GENERIC_BITOPS_INSTRUMENTED_ATOMIC_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/instrumented.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * set_bit - Atomically set a bit in memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * @nr: the bit to set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * @addr: the address to start counting from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * This is a relaxed atomic operation (no implied memory barriers).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * Note that @nr may be almost arbitrarily large; this function is not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * restricted to acting on a single-word quantity.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) static inline void set_bit(long nr, volatile unsigned long *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) instrument_atomic_write(addr + BIT_WORD(nr), sizeof(long));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) arch_set_bit(nr, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * clear_bit - Clears a bit in memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * @nr: Bit to clear
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * @addr: Address to start counting from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * This is a relaxed atomic operation (no implied memory barriers).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) static inline void clear_bit(long nr, volatile unsigned long *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) instrument_atomic_write(addr + BIT_WORD(nr), sizeof(long));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) arch_clear_bit(nr, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * change_bit - Toggle a bit in memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * @nr: Bit to change
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * @addr: Address to start counting from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * This is a relaxed atomic operation (no implied memory barriers).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * Note that @nr may be almost arbitrarily large; this function is not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * restricted to acting on a single-word quantity.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) static inline void change_bit(long nr, volatile unsigned long *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) instrument_atomic_write(addr + BIT_WORD(nr), sizeof(long));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) arch_change_bit(nr, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) * test_and_set_bit - Set a bit and return its old value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * @nr: Bit to set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) * @addr: Address to count from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) * This is an atomic fully-ordered operation (implied full memory barrier).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) static inline bool test_and_set_bit(long nr, volatile unsigned long *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) instrument_atomic_read_write(addr + BIT_WORD(nr), sizeof(long));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) return arch_test_and_set_bit(nr, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * test_and_clear_bit - Clear a bit and return its old value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * @nr: Bit to clear
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * @addr: Address to count from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * This is an atomic fully-ordered operation (implied full memory barrier).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) static inline bool test_and_clear_bit(long nr, volatile unsigned long *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) instrument_atomic_read_write(addr + BIT_WORD(nr), sizeof(long));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) return arch_test_and_clear_bit(nr, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * test_and_change_bit - Change a bit and return its old value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * @nr: Bit to change
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * @addr: Address to count from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * This is an atomic fully-ordered operation (implied full memory barrier).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) static inline bool test_and_change_bit(long nr, volatile unsigned long *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) instrument_atomic_read_write(addr + BIT_WORD(nr), sizeof(long));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) return arch_test_and_change_bit(nr, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #endif /* _ASM_GENERIC_BITOPS_INSTRUMENTED_NON_ATOMIC_H */