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-cas.h (2001B)


      1/* SPDX-License-Identifier: GPL-2.0
      2 *
      3 * include/asm-sh/spinlock-cas.h
      4 *
      5 * Copyright (C) 2015 SEI
      6 */
      7#ifndef __ASM_SH_SPINLOCK_CAS_H
      8#define __ASM_SH_SPINLOCK_CAS_H
      9
     10#include <asm/barrier.h>
     11#include <asm/processor.h>
     12
     13static inline unsigned __sl_cas(volatile unsigned *p, unsigned old, unsigned new)
     14{
     15	__asm__ __volatile__("cas.l %1,%0,@r0"
     16		: "+r"(new)
     17		: "r"(old), "z"(p)
     18		: "t", "memory" );
     19	return new;
     20}
     21
     22/*
     23 * Your basic SMP spinlocks, allowing only a single CPU anywhere
     24 */
     25
     26#define arch_spin_is_locked(x)		((x)->lock <= 0)
     27
     28static inline void arch_spin_lock(arch_spinlock_t *lock)
     29{
     30	while (!__sl_cas(&lock->lock, 1, 0));
     31}
     32
     33static inline void arch_spin_unlock(arch_spinlock_t *lock)
     34{
     35	__sl_cas(&lock->lock, 0, 1);
     36}
     37
     38static inline int arch_spin_trylock(arch_spinlock_t *lock)
     39{
     40	return __sl_cas(&lock->lock, 1, 0);
     41}
     42
     43/*
     44 * Read-write spinlocks, allowing multiple readers but only one writer.
     45 *
     46 * NOTE! it is quite common to have readers in interrupts but no interrupt
     47 * writers. For those circumstances we can "mix" irq-safe locks - any writer
     48 * needs to get a irq-safe write-lock, but readers can get non-irqsafe
     49 * read-locks.
     50 */
     51
     52static inline void arch_read_lock(arch_rwlock_t *rw)
     53{
     54	unsigned old;
     55	do old = rw->lock;
     56	while (!old || __sl_cas(&rw->lock, old, old-1) != old);
     57}
     58
     59static inline void arch_read_unlock(arch_rwlock_t *rw)
     60{
     61	unsigned old;
     62	do old = rw->lock;
     63	while (__sl_cas(&rw->lock, old, old+1) != old);
     64}
     65
     66static inline void arch_write_lock(arch_rwlock_t *rw)
     67{
     68	while (__sl_cas(&rw->lock, RW_LOCK_BIAS, 0) != RW_LOCK_BIAS);
     69}
     70
     71static inline void arch_write_unlock(arch_rwlock_t *rw)
     72{
     73	__sl_cas(&rw->lock, 0, RW_LOCK_BIAS);
     74}
     75
     76static inline int arch_read_trylock(arch_rwlock_t *rw)
     77{
     78	unsigned old;
     79	do old = rw->lock;
     80	while (old && __sl_cas(&rw->lock, old, old-1) != old);
     81	return !!old;
     82}
     83
     84static inline int arch_write_trylock(arch_rwlock_t *rw)
     85{
     86	return __sl_cas(&rw->lock, RW_LOCK_BIAS, 0) == RW_LOCK_BIAS;
     87}
     88
     89#endif /* __ASM_SH_SPINLOCK_CAS_H */