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

cmpxchg.h (3149B)


      1/* SPDX-License-Identifier: GPL-2.0 */
      2#ifndef __ARCH_M68K_CMPXCHG__
      3#define __ARCH_M68K_CMPXCHG__
      4
      5#include <linux/irqflags.h>
      6
      7#define __xg(type, x) ((volatile type *)(x))
      8
      9extern unsigned long __invalid_xchg_size(unsigned long, volatile void *, int);
     10
     11#ifndef CONFIG_RMW_INSNS
     12static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
     13{
     14	unsigned long flags, tmp;
     15
     16	local_irq_save(flags);
     17
     18	switch (size) {
     19	case 1:
     20		tmp = *(u8 *)ptr;
     21		*(u8 *)ptr = x;
     22		x = tmp;
     23		break;
     24	case 2:
     25		tmp = *(u16 *)ptr;
     26		*(u16 *)ptr = x;
     27		x = tmp;
     28		break;
     29	case 4:
     30		tmp = *(u32 *)ptr;
     31		*(u32 *)ptr = x;
     32		x = tmp;
     33		break;
     34	default:
     35		tmp = __invalid_xchg_size(x, ptr, size);
     36		break;
     37	}
     38
     39	local_irq_restore(flags);
     40	return x;
     41}
     42#else
     43static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
     44{
     45	switch (size) {
     46	case 1:
     47		__asm__ __volatile__
     48			("moveb %2,%0\n\t"
     49			 "1:\n\t"
     50			 "casb %0,%1,%2\n\t"
     51			 "jne 1b"
     52			 : "=&d" (x) : "d" (x), "m" (*__xg(u8, ptr)) : "memory");
     53		break;
     54	case 2:
     55		__asm__ __volatile__
     56			("movew %2,%0\n\t"
     57			 "1:\n\t"
     58			 "casw %0,%1,%2\n\t"
     59			 "jne 1b"
     60			 : "=&d" (x) : "d" (x), "m" (*__xg(u16, ptr)) : "memory");
     61		break;
     62	case 4:
     63		__asm__ __volatile__
     64			("movel %2,%0\n\t"
     65			 "1:\n\t"
     66			 "casl %0,%1,%2\n\t"
     67			 "jne 1b"
     68			 : "=&d" (x) : "d" (x), "m" (*__xg(u32, ptr)) : "memory");
     69		break;
     70	default:
     71		x = __invalid_xchg_size(x, ptr, size);
     72		break;
     73	}
     74	return x;
     75}
     76#endif
     77
     78#define arch_xchg(ptr,x) ({(__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)));})
     79
     80#include <asm-generic/cmpxchg-local.h>
     81
     82#define arch_cmpxchg64_local(ptr, o, n) __generic_cmpxchg64_local((ptr), (o), (n))
     83
     84extern unsigned long __invalid_cmpxchg_size(volatile void *,
     85					    unsigned long, unsigned long, int);
     86
     87/*
     88 * Atomic compare and exchange.  Compare OLD with MEM, if identical,
     89 * store NEW in MEM.  Return the initial value in MEM.  Success is
     90 * indicated by comparing RETURN with OLD.
     91 */
     92#ifdef CONFIG_RMW_INSNS
     93
     94static inline unsigned long __cmpxchg(volatile void *p, unsigned long old,
     95				      unsigned long new, int size)
     96{
     97	switch (size) {
     98	case 1:
     99		__asm__ __volatile__ ("casb %0,%2,%1"
    100				      : "=d" (old), "=m" (*(char *)p)
    101				      : "d" (new), "0" (old), "m" (*(char *)p));
    102		break;
    103	case 2:
    104		__asm__ __volatile__ ("casw %0,%2,%1"
    105				      : "=d" (old), "=m" (*(short *)p)
    106				      : "d" (new), "0" (old), "m" (*(short *)p));
    107		break;
    108	case 4:
    109		__asm__ __volatile__ ("casl %0,%2,%1"
    110				      : "=d" (old), "=m" (*(int *)p)
    111				      : "d" (new), "0" (old), "m" (*(int *)p));
    112		break;
    113	default:
    114		old = __invalid_cmpxchg_size(p, old, new, size);
    115		break;
    116	}
    117	return old;
    118}
    119
    120#define arch_cmpxchg(ptr, o, n)						    \
    121	({(__typeof__(*(ptr)))__cmpxchg((ptr), (unsigned long)(o),	    \
    122			(unsigned long)(n), sizeof(*(ptr)));})
    123#define arch_cmpxchg_local(ptr, o, n)					    \
    124	({(__typeof__(*(ptr)))__cmpxchg((ptr), (unsigned long)(o),	    \
    125			(unsigned long)(n), sizeof(*(ptr)));})
    126
    127#define arch_cmpxchg64(ptr, o, n)	arch_cmpxchg64_local((ptr), (o), (n))
    128
    129#else
    130
    131#include <asm-generic/cmpxchg.h>
    132
    133#endif
    134
    135#endif /* __ARCH_M68K_CMPXCHG__ */