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

spinlock.h (2915B)


      1/* SPDX-License-Identifier: GPL-2.0 */
      2#ifndef _ALPHA_SPINLOCK_H
      3#define _ALPHA_SPINLOCK_H
      4
      5#include <linux/kernel.h>
      6#include <asm/current.h>
      7#include <asm/barrier.h>
      8#include <asm/processor.h>
      9
     10/*
     11 * Simple spin lock operations.  There are two variants, one clears IRQ's
     12 * on the local processor, one does not.
     13 *
     14 * We make no fairness assumptions. They have a cost.
     15 */
     16
     17#define arch_spin_is_locked(x)	((x)->lock != 0)
     18
     19static inline int arch_spin_value_unlocked(arch_spinlock_t lock)
     20{
     21        return lock.lock == 0;
     22}
     23
     24static inline void arch_spin_unlock(arch_spinlock_t * lock)
     25{
     26	mb();
     27	lock->lock = 0;
     28}
     29
     30static inline void arch_spin_lock(arch_spinlock_t * lock)
     31{
     32	long tmp;
     33
     34	__asm__ __volatile__(
     35	"1:	ldl_l	%0,%1\n"
     36	"	bne	%0,2f\n"
     37	"	lda	%0,1\n"
     38	"	stl_c	%0,%1\n"
     39	"	beq	%0,2f\n"
     40	"	mb\n"
     41	".subsection 2\n"
     42	"2:	ldl	%0,%1\n"
     43	"	bne	%0,2b\n"
     44	"	br	1b\n"
     45	".previous"
     46	: "=&r" (tmp), "=m" (lock->lock)
     47	: "m"(lock->lock) : "memory");
     48}
     49
     50static inline int arch_spin_trylock(arch_spinlock_t *lock)
     51{
     52	return !test_and_set_bit(0, &lock->lock);
     53}
     54
     55/***********************************************************/
     56
     57static inline void arch_read_lock(arch_rwlock_t *lock)
     58{
     59	long regx;
     60
     61	__asm__ __volatile__(
     62	"1:	ldl_l	%1,%0\n"
     63	"	blbs	%1,6f\n"
     64	"	subl	%1,2,%1\n"
     65	"	stl_c	%1,%0\n"
     66	"	beq	%1,6f\n"
     67	"	mb\n"
     68	".subsection 2\n"
     69	"6:	ldl	%1,%0\n"
     70	"	blbs	%1,6b\n"
     71	"	br	1b\n"
     72	".previous"
     73	: "=m" (*lock), "=&r" (regx)
     74	: "m" (*lock) : "memory");
     75}
     76
     77static inline void arch_write_lock(arch_rwlock_t *lock)
     78{
     79	long regx;
     80
     81	__asm__ __volatile__(
     82	"1:	ldl_l	%1,%0\n"
     83	"	bne	%1,6f\n"
     84	"	lda	%1,1\n"
     85	"	stl_c	%1,%0\n"
     86	"	beq	%1,6f\n"
     87	"	mb\n"
     88	".subsection 2\n"
     89	"6:	ldl	%1,%0\n"
     90	"	bne	%1,6b\n"
     91	"	br	1b\n"
     92	".previous"
     93	: "=m" (*lock), "=&r" (regx)
     94	: "m" (*lock) : "memory");
     95}
     96
     97static inline int arch_read_trylock(arch_rwlock_t * lock)
     98{
     99	long regx;
    100	int success;
    101
    102	__asm__ __volatile__(
    103	"1:	ldl_l	%1,%0\n"
    104	"	lda	%2,0\n"
    105	"	blbs	%1,2f\n"
    106	"	subl	%1,2,%2\n"
    107	"	stl_c	%2,%0\n"
    108	"	beq	%2,6f\n"
    109	"2:	mb\n"
    110	".subsection 2\n"
    111	"6:	br	1b\n"
    112	".previous"
    113	: "=m" (*lock), "=&r" (regx), "=&r" (success)
    114	: "m" (*lock) : "memory");
    115
    116	return success;
    117}
    118
    119static inline int arch_write_trylock(arch_rwlock_t * lock)
    120{
    121	long regx;
    122	int success;
    123
    124	__asm__ __volatile__(
    125	"1:	ldl_l	%1,%0\n"
    126	"	lda	%2,0\n"
    127	"	bne	%1,2f\n"
    128	"	lda	%2,1\n"
    129	"	stl_c	%2,%0\n"
    130	"	beq	%2,6f\n"
    131	"2:	mb\n"
    132	".subsection 2\n"
    133	"6:	br	1b\n"
    134	".previous"
    135	: "=m" (*lock), "=&r" (regx), "=&r" (success)
    136	: "m" (*lock) : "memory");
    137
    138	return success;
    139}
    140
    141static inline void arch_read_unlock(arch_rwlock_t * lock)
    142{
    143	long regx;
    144	__asm__ __volatile__(
    145	"	mb\n"
    146	"1:	ldl_l	%1,%0\n"
    147	"	addl	%1,2,%1\n"
    148	"	stl_c	%1,%0\n"
    149	"	beq	%1,6f\n"
    150	".subsection 2\n"
    151	"6:	br	1b\n"
    152	".previous"
    153	: "=m" (*lock), "=&r" (regx)
    154	: "m" (*lock) : "memory");
    155}
    156
    157static inline void arch_write_unlock(arch_rwlock_t * lock)
    158{
    159	mb();
    160	lock->lock = 0;
    161}
    162
    163#endif /* _ALPHA_SPINLOCK_H */