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-local.h (1464B)


      1/* SPDX-License-Identifier: GPL-2.0 */
      2#ifndef __ASM_GENERIC_CMPXCHG_LOCAL_H
      3#define __ASM_GENERIC_CMPXCHG_LOCAL_H
      4
      5#include <linux/types.h>
      6#include <linux/irqflags.h>
      7
      8extern unsigned long wrong_size_cmpxchg(volatile void *ptr)
      9	__noreturn;
     10
     11/*
     12 * Generic version of __cmpxchg_local (disables interrupts). Takes an unsigned
     13 * long parameter, supporting various types of architectures.
     14 */
     15static inline unsigned long __generic_cmpxchg_local(volatile void *ptr,
     16		unsigned long old, unsigned long new, int size)
     17{
     18	unsigned long flags, prev;
     19
     20	/*
     21	 * Sanity checking, compile-time.
     22	 */
     23	if (size == 8 && sizeof(unsigned long) != 8)
     24		wrong_size_cmpxchg(ptr);
     25
     26	raw_local_irq_save(flags);
     27	switch (size) {
     28	case 1: prev = *(u8 *)ptr;
     29		if (prev == old)
     30			*(u8 *)ptr = (u8)new;
     31		break;
     32	case 2: prev = *(u16 *)ptr;
     33		if (prev == old)
     34			*(u16 *)ptr = (u16)new;
     35		break;
     36	case 4: prev = *(u32 *)ptr;
     37		if (prev == old)
     38			*(u32 *)ptr = (u32)new;
     39		break;
     40	case 8: prev = *(u64 *)ptr;
     41		if (prev == old)
     42			*(u64 *)ptr = (u64)new;
     43		break;
     44	default:
     45		wrong_size_cmpxchg(ptr);
     46	}
     47	raw_local_irq_restore(flags);
     48	return prev;
     49}
     50
     51/*
     52 * Generic version of __cmpxchg64_local. Takes an u64 parameter.
     53 */
     54static inline u64 __generic_cmpxchg64_local(volatile void *ptr,
     55		u64 old, u64 new)
     56{
     57	u64 prev;
     58	unsigned long flags;
     59
     60	raw_local_irq_save(flags);
     61	prev = *(u64 *)ptr;
     62	if (prev == old)
     63		*(u64 *)ptr = new;
     64	raw_local_irq_restore(flags);
     65	return prev;
     66}
     67
     68#endif