cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

non-atomic.h (3550B)


      1/* SPDX-License-Identifier: GPL-2.0 */
      2#ifndef _ASM_GENERIC_BITOPS_NON_ATOMIC_H_
      3#define _ASM_GENERIC_BITOPS_NON_ATOMIC_H_
      4
      5#include <asm/types.h>
      6
      7/**
      8 * arch___set_bit - Set a bit in memory
      9 * @nr: the bit to set
     10 * @addr: the address to start counting from
     11 *
     12 * Unlike set_bit(), this function is non-atomic and may be reordered.
     13 * If it's called on the same region of memory simultaneously, the effect
     14 * may be that only one operation succeeds.
     15 */
     16static __always_inline void
     17arch___set_bit(unsigned int nr, volatile unsigned long *addr)
     18{
     19	unsigned long mask = BIT_MASK(nr);
     20	unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
     21
     22	*p  |= mask;
     23}
     24#define __set_bit arch___set_bit
     25
     26static __always_inline void
     27arch___clear_bit(unsigned int nr, volatile unsigned long *addr)
     28{
     29	unsigned long mask = BIT_MASK(nr);
     30	unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
     31
     32	*p &= ~mask;
     33}
     34#define __clear_bit arch___clear_bit
     35
     36/**
     37 * arch___change_bit - Toggle a bit in memory
     38 * @nr: the bit to change
     39 * @addr: the address to start counting from
     40 *
     41 * Unlike change_bit(), this function is non-atomic and may be reordered.
     42 * If it's called on the same region of memory simultaneously, the effect
     43 * may be that only one operation succeeds.
     44 */
     45static __always_inline
     46void arch___change_bit(unsigned int nr, volatile unsigned long *addr)
     47{
     48	unsigned long mask = BIT_MASK(nr);
     49	unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
     50
     51	*p ^= mask;
     52}
     53#define __change_bit arch___change_bit
     54
     55/**
     56 * arch___test_and_set_bit - Set a bit and return its old value
     57 * @nr: Bit to set
     58 * @addr: Address to count from
     59 *
     60 * This operation is non-atomic and can be reordered.
     61 * If two examples of this operation race, one can appear to succeed
     62 * but actually fail.  You must protect multiple accesses with a lock.
     63 */
     64static __always_inline int
     65arch___test_and_set_bit(unsigned int nr, volatile unsigned long *addr)
     66{
     67	unsigned long mask = BIT_MASK(nr);
     68	unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
     69	unsigned long old = *p;
     70
     71	*p = old | mask;
     72	return (old & mask) != 0;
     73}
     74#define __test_and_set_bit arch___test_and_set_bit
     75
     76/**
     77 * arch___test_and_clear_bit - Clear a bit and return its old value
     78 * @nr: Bit to clear
     79 * @addr: Address to count from
     80 *
     81 * This operation is non-atomic and can be reordered.
     82 * If two examples of this operation race, one can appear to succeed
     83 * but actually fail.  You must protect multiple accesses with a lock.
     84 */
     85static __always_inline int
     86arch___test_and_clear_bit(unsigned int nr, volatile unsigned long *addr)
     87{
     88	unsigned long mask = BIT_MASK(nr);
     89	unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
     90	unsigned long old = *p;
     91
     92	*p = old & ~mask;
     93	return (old & mask) != 0;
     94}
     95#define __test_and_clear_bit arch___test_and_clear_bit
     96
     97/* WARNING: non atomic and it can be reordered! */
     98static __always_inline int
     99arch___test_and_change_bit(unsigned int nr, volatile unsigned long *addr)
    100{
    101	unsigned long mask = BIT_MASK(nr);
    102	unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
    103	unsigned long old = *p;
    104
    105	*p = old ^ mask;
    106	return (old & mask) != 0;
    107}
    108#define __test_and_change_bit arch___test_and_change_bit
    109
    110/**
    111 * arch_test_bit - Determine whether a bit is set
    112 * @nr: bit number to test
    113 * @addr: Address to start counting from
    114 */
    115static __always_inline int
    116arch_test_bit(unsigned int nr, const volatile unsigned long *addr)
    117{
    118	return 1UL & (addr[BIT_WORD(nr)] >> (nr & (BITS_PER_LONG-1)));
    119}
    120#define test_bit arch_test_bit
    121
    122#endif /* _ASM_GENERIC_BITOPS_NON_ATOMIC_H_ */