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

bitops.c (3845B)


      1/*
      2 * This file is subject to the terms and conditions of the GNU General Public
      3 * License.  See the file "COPYING" in the main directory of this archive
      4 * for more details.
      5 *
      6 * Copyright (c) 1994-1997, 99, 2000, 06, 07 Ralf Baechle (ralf@linux-mips.org)
      7 * Copyright (c) 1999, 2000  Silicon Graphics, Inc.
      8 */
      9#include <linux/bitops.h>
     10#include <linux/bits.h>
     11#include <linux/irqflags.h>
     12#include <linux/export.h>
     13
     14
     15/**
     16 * __mips_set_bit - Atomically set a bit in memory.  This is called by
     17 * set_bit() if it cannot find a faster solution.
     18 * @nr: the bit to set
     19 * @addr: the address to start counting from
     20 */
     21void __mips_set_bit(unsigned long nr, volatile unsigned long *addr)
     22{
     23	volatile unsigned long *a = &addr[BIT_WORD(nr)];
     24	unsigned int bit = nr % BITS_PER_LONG;
     25	unsigned long mask;
     26	unsigned long flags;
     27
     28	mask = 1UL << bit;
     29	raw_local_irq_save(flags);
     30	*a |= mask;
     31	raw_local_irq_restore(flags);
     32}
     33EXPORT_SYMBOL(__mips_set_bit);
     34
     35
     36/**
     37 * __mips_clear_bit - Clears a bit in memory.  This is called by clear_bit() if
     38 * it cannot find a faster solution.
     39 * @nr: Bit to clear
     40 * @addr: Address to start counting from
     41 */
     42void __mips_clear_bit(unsigned long nr, volatile unsigned long *addr)
     43{
     44	volatile unsigned long *a = &addr[BIT_WORD(nr)];
     45	unsigned int bit = nr % BITS_PER_LONG;
     46	unsigned long mask;
     47	unsigned long flags;
     48
     49	mask = 1UL << bit;
     50	raw_local_irq_save(flags);
     51	*a &= ~mask;
     52	raw_local_irq_restore(flags);
     53}
     54EXPORT_SYMBOL(__mips_clear_bit);
     55
     56
     57/**
     58 * __mips_change_bit - Toggle a bit in memory.	This is called by change_bit()
     59 * if it cannot find a faster solution.
     60 * @nr: Bit to change
     61 * @addr: Address to start counting from
     62 */
     63void __mips_change_bit(unsigned long nr, volatile unsigned long *addr)
     64{
     65	volatile unsigned long *a = &addr[BIT_WORD(nr)];
     66	unsigned int bit = nr % BITS_PER_LONG;
     67	unsigned long mask;
     68	unsigned long flags;
     69
     70	mask = 1UL << bit;
     71	raw_local_irq_save(flags);
     72	*a ^= mask;
     73	raw_local_irq_restore(flags);
     74}
     75EXPORT_SYMBOL(__mips_change_bit);
     76
     77
     78/**
     79 * __mips_test_and_set_bit_lock - Set a bit and return its old value.  This is
     80 * called by test_and_set_bit_lock() if it cannot find a faster solution.
     81 * @nr: Bit to set
     82 * @addr: Address to count from
     83 */
     84int __mips_test_and_set_bit_lock(unsigned long nr,
     85				 volatile unsigned long *addr)
     86{
     87	volatile unsigned long *a = &addr[BIT_WORD(nr)];
     88	unsigned int bit = nr % BITS_PER_LONG;
     89	unsigned long mask;
     90	unsigned long flags;
     91	int res;
     92
     93	mask = 1UL << bit;
     94	raw_local_irq_save(flags);
     95	res = (mask & *a) != 0;
     96	*a |= mask;
     97	raw_local_irq_restore(flags);
     98	return res;
     99}
    100EXPORT_SYMBOL(__mips_test_and_set_bit_lock);
    101
    102
    103/**
    104 * __mips_test_and_clear_bit - Clear a bit and return its old value.  This is
    105 * called by test_and_clear_bit() if it cannot find a faster solution.
    106 * @nr: Bit to clear
    107 * @addr: Address to count from
    108 */
    109int __mips_test_and_clear_bit(unsigned long nr, volatile unsigned long *addr)
    110{
    111	volatile unsigned long *a = &addr[BIT_WORD(nr)];
    112	unsigned int bit = nr % BITS_PER_LONG;
    113	unsigned long mask;
    114	unsigned long flags;
    115	int res;
    116
    117	mask = 1UL << bit;
    118	raw_local_irq_save(flags);
    119	res = (mask & *a) != 0;
    120	*a &= ~mask;
    121	raw_local_irq_restore(flags);
    122	return res;
    123}
    124EXPORT_SYMBOL(__mips_test_and_clear_bit);
    125
    126
    127/**
    128 * __mips_test_and_change_bit - Change a bit and return its old value.	This is
    129 * called by test_and_change_bit() if it cannot find a faster solution.
    130 * @nr: Bit to change
    131 * @addr: Address to count from
    132 */
    133int __mips_test_and_change_bit(unsigned long nr, volatile unsigned long *addr)
    134{
    135	volatile unsigned long *a = &addr[BIT_WORD(nr)];
    136	unsigned int bit = nr % BITS_PER_LONG;
    137	unsigned long mask;
    138	unsigned long flags;
    139	int res;
    140
    141	mask = 1UL << bit;
    142	raw_local_irq_save(flags);
    143	res = (mask & *a) != 0;
    144	*a ^= mask;
    145	raw_local_irq_restore(flags);
    146	return res;
    147}
    148EXPORT_SYMBOL(__mips_test_and_change_bit);