Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 
0003 /*
0004  * This file provides wrappers with sanitizer instrumentation for atomic bit
0005  * operations.
0006  *
0007  * To use this functionality, an arch's bitops.h file needs to define each of
0008  * the below bit operations with an arch_ prefix (e.g. arch_set_bit(),
0009  * arch___set_bit(), etc.).
0010  */
0011 #ifndef _ASM_GENERIC_BITOPS_INSTRUMENTED_ATOMIC_H
0012 #define _ASM_GENERIC_BITOPS_INSTRUMENTED_ATOMIC_H
0013 
0014 #include <linux/instrumented.h>
0015 
0016 /**
0017  * set_bit - Atomically set a bit in memory
0018  * @nr: the bit to set
0019  * @addr: the address to start counting from
0020  *
0021  * This is a relaxed atomic operation (no implied memory barriers).
0022  *
0023  * Note that @nr may be almost arbitrarily large; this function is not
0024  * restricted to acting on a single-word quantity.
0025  */
0026 static __always_inline void set_bit(long nr, volatile unsigned long *addr)
0027 {
0028     instrument_atomic_write(addr + BIT_WORD(nr), sizeof(long));
0029     arch_set_bit(nr, addr);
0030 }
0031 
0032 /**
0033  * clear_bit - Clears a bit in memory
0034  * @nr: Bit to clear
0035  * @addr: Address to start counting from
0036  *
0037  * This is a relaxed atomic operation (no implied memory barriers).
0038  */
0039 static __always_inline void clear_bit(long nr, volatile unsigned long *addr)
0040 {
0041     instrument_atomic_write(addr + BIT_WORD(nr), sizeof(long));
0042     arch_clear_bit(nr, addr);
0043 }
0044 
0045 /**
0046  * change_bit - Toggle a bit in memory
0047  * @nr: Bit to change
0048  * @addr: Address to start counting from
0049  *
0050  * This is a relaxed atomic operation (no implied memory barriers).
0051  *
0052  * Note that @nr may be almost arbitrarily large; this function is not
0053  * restricted to acting on a single-word quantity.
0054  */
0055 static __always_inline void change_bit(long nr, volatile unsigned long *addr)
0056 {
0057     instrument_atomic_write(addr + BIT_WORD(nr), sizeof(long));
0058     arch_change_bit(nr, addr);
0059 }
0060 
0061 /**
0062  * test_and_set_bit - Set a bit and return its old value
0063  * @nr: Bit to set
0064  * @addr: Address to count from
0065  *
0066  * This is an atomic fully-ordered operation (implied full memory barrier).
0067  */
0068 static __always_inline bool test_and_set_bit(long nr, volatile unsigned long *addr)
0069 {
0070     kcsan_mb();
0071     instrument_atomic_read_write(addr + BIT_WORD(nr), sizeof(long));
0072     return arch_test_and_set_bit(nr, addr);
0073 }
0074 
0075 /**
0076  * test_and_clear_bit - Clear a bit and return its old value
0077  * @nr: Bit to clear
0078  * @addr: Address to count from
0079  *
0080  * This is an atomic fully-ordered operation (implied full memory barrier).
0081  */
0082 static __always_inline bool test_and_clear_bit(long nr, volatile unsigned long *addr)
0083 {
0084     kcsan_mb();
0085     instrument_atomic_read_write(addr + BIT_WORD(nr), sizeof(long));
0086     return arch_test_and_clear_bit(nr, addr);
0087 }
0088 
0089 /**
0090  * test_and_change_bit - Change a bit and return its old value
0091  * @nr: Bit to change
0092  * @addr: Address to count from
0093  *
0094  * This is an atomic fully-ordered operation (implied full memory barrier).
0095  */
0096 static __always_inline bool test_and_change_bit(long nr, volatile unsigned long *addr)
0097 {
0098     kcsan_mb();
0099     instrument_atomic_read_write(addr + BIT_WORD(nr), sizeof(long));
0100     return arch_test_and_change_bit(nr, addr);
0101 }
0102 
0103 #endif /* _ASM_GENERIC_BITOPS_INSTRUMENTED_NON_ATOMIC_H */