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

mips-atomic.c (2787B)


      1/*
      2 * This file is subject to the terms and conditions of the GNU General Public
      3 * License.  See the file "COPYING" in the main directory of this archive
      4 * for more details.
      5 *
      6 * Copyright (C) 1994, 95, 96, 97, 98, 99, 2003 by Ralf Baechle
      7 * Copyright (C) 1996 by Paul M. Antoine
      8 * Copyright (C) 1999 Silicon Graphics
      9 * Copyright (C) 2000 MIPS Technologies, Inc.
     10 */
     11#include <asm/irqflags.h>
     12#include <asm/hazards.h>
     13#include <linux/compiler.h>
     14#include <linux/preempt.h>
     15#include <linux/export.h>
     16#include <linux/stringify.h>
     17
     18#if !defined(CONFIG_CPU_HAS_DIEI)
     19
     20/*
     21 * For cli() we have to insert nops to make sure that the new value
     22 * has actually arrived in the status register before the end of this
     23 * macro.
     24 * R4000/R4400 need three nops, the R4600 two nops and the R10000 needs
     25 * no nops at all.
     26 */
     27/*
     28 * For TX49, operating only IE bit is not enough.
     29 *
     30 * If mfc0 $12 follows store and the mfc0 is last instruction of a
     31 * page and fetching the next instruction causes TLB miss, the result
     32 * of the mfc0 might wrongly contain EXL bit.
     33 *
     34 * ERT-TX49H2-027, ERT-TX49H3-012, ERT-TX49HL3-006, ERT-TX49H4-008
     35 *
     36 * Workaround: mask EXL bit of the result or place a nop before mfc0.
     37 */
     38notrace void arch_local_irq_disable(void)
     39{
     40	preempt_disable_notrace();
     41
     42	__asm__ __volatile__(
     43	"	.set	push						\n"
     44	"	.set	noat						\n"
     45	"	mfc0	$1,$12						\n"
     46	"	ori	$1,0x1f						\n"
     47	"	xori	$1,0x1f						\n"
     48	"	.set	noreorder					\n"
     49	"	mtc0	$1,$12						\n"
     50	"	" __stringify(__irq_disable_hazard) "			\n"
     51	"	.set	pop						\n"
     52	: /* no outputs */
     53	: /* no inputs */
     54	: "memory");
     55
     56	preempt_enable_notrace();
     57}
     58EXPORT_SYMBOL(arch_local_irq_disable);
     59
     60notrace unsigned long arch_local_irq_save(void)
     61{
     62	unsigned long flags;
     63
     64	preempt_disable_notrace();
     65
     66	__asm__ __volatile__(
     67	"	.set	push						\n"
     68	"	.set	reorder						\n"
     69	"	.set	noat						\n"
     70	"	mfc0	%[flags], $12					\n"
     71	"	ori	$1, %[flags], 0x1f				\n"
     72	"	xori	$1, 0x1f					\n"
     73	"	.set	noreorder					\n"
     74	"	mtc0	$1, $12						\n"
     75	"	" __stringify(__irq_disable_hazard) "			\n"
     76	"	.set	pop						\n"
     77	: [flags] "=r" (flags)
     78	: /* no inputs */
     79	: "memory");
     80
     81	preempt_enable_notrace();
     82
     83	return flags;
     84}
     85EXPORT_SYMBOL(arch_local_irq_save);
     86
     87notrace void arch_local_irq_restore(unsigned long flags)
     88{
     89	unsigned long __tmp1;
     90
     91	preempt_disable_notrace();
     92
     93	__asm__ __volatile__(
     94	"	.set	push						\n"
     95	"	.set	noreorder					\n"
     96	"	.set	noat						\n"
     97	"	mfc0	$1, $12						\n"
     98	"	andi	%[flags], 1					\n"
     99	"	ori	$1, 0x1f					\n"
    100	"	xori	$1, 0x1f					\n"
    101	"	or	%[flags], $1					\n"
    102	"	mtc0	%[flags], $12					\n"
    103	"	" __stringify(__irq_disable_hazard) "			\n"
    104	"	.set	pop						\n"
    105	: [flags] "=r" (__tmp1)
    106	: "0" (flags)
    107	: "memory");
    108
    109	preempt_enable_notrace();
    110}
    111EXPORT_SYMBOL(arch_local_irq_restore);
    112
    113#endif /* !CONFIG_CPU_HAS_DIEI */