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-xchg.h (1274B)


      1/* SPDX-License-Identifier: GPL-2.0 */
      2#ifndef __ASM_SH_CMPXCHG_XCHG_H
      3#define __ASM_SH_CMPXCHG_XCHG_H
      4
      5/*
      6 * Copyright (C) 2016 Red Hat, Inc.
      7 * Author: Michael S. Tsirkin <mst@redhat.com>
      8 */
      9#include <linux/bits.h>
     10#include <linux/compiler.h>
     11#include <asm/byteorder.h>
     12
     13/*
     14 * Portable implementations of 1 and 2 byte xchg using a 4 byte cmpxchg.
     15 * Note: this header isn't self-contained: before including it, __cmpxchg_u32
     16 * must be defined first.
     17 */
     18static inline u32 __xchg_cmpxchg(volatile void *ptr, u32 x, int size)
     19{
     20	int off = (unsigned long)ptr % sizeof(u32);
     21	volatile u32 *p = ptr - off;
     22#ifdef __BIG_ENDIAN
     23	int bitoff = (sizeof(u32) - size - off) * BITS_PER_BYTE;
     24#else
     25	int bitoff = off * BITS_PER_BYTE;
     26#endif
     27	u32 bitmask = ((0x1 << size * BITS_PER_BYTE) - 1) << bitoff;
     28	u32 oldv, newv;
     29	u32 ret;
     30
     31	do {
     32		oldv = READ_ONCE(*p);
     33		ret = (oldv & bitmask) >> bitoff;
     34		newv = (oldv & ~bitmask) | (x << bitoff);
     35	} while (__cmpxchg_u32(p, oldv, newv) != oldv);
     36
     37	return ret;
     38}
     39
     40static inline unsigned long xchg_u16(volatile u16 *m, unsigned long val)
     41{
     42	return __xchg_cmpxchg(m, val, sizeof *m);
     43}
     44
     45static inline unsigned long xchg_u8(volatile u8 *m, unsigned long val)
     46{
     47	return __xchg_cmpxchg(m, val, sizeof *m);
     48}
     49
     50#endif /* __ASM_SH_CMPXCHG_XCHG_H */