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

irqflags.h (4206B)


      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#ifndef _ASM_IRQFLAGS_H
     12#define _ASM_IRQFLAGS_H
     13
     14#ifndef __ASSEMBLY__
     15
     16#include <linux/compiler.h>
     17#include <linux/stringify.h>
     18#include <asm/compiler.h>
     19#include <asm/hazards.h>
     20
     21#if defined(CONFIG_CPU_HAS_DIEI)
     22
     23static inline void arch_local_irq_disable(void)
     24{
     25	__asm__ __volatile__(
     26	"	.set	push						\n"
     27	"	.set	noat						\n"
     28	"	di							\n"
     29	"	" __stringify(__irq_disable_hazard) "			\n"
     30	"	.set	pop						\n"
     31	: /* no outputs */
     32	: /* no inputs */
     33	: "memory");
     34}
     35
     36static inline unsigned long arch_local_irq_save(void)
     37{
     38	unsigned long flags;
     39
     40	asm __volatile__(
     41	"	.set	push						\n"
     42	"	.set	reorder						\n"
     43	"	.set	noat						\n"
     44#if defined(CONFIG_CPU_LOONGSON64) || defined(CONFIG_CPU_LOONGSON32)
     45	"	mfc0	%[flags], $12					\n"
     46	"	di							\n"
     47#else
     48	"	di	%[flags]					\n"
     49#endif
     50	"	andi	%[flags], 1					\n"
     51	"	" __stringify(__irq_disable_hazard) "			\n"
     52	"	.set	pop						\n"
     53	: [flags] "=r" (flags)
     54	: /* no inputs */
     55	: "memory");
     56
     57	return flags;
     58}
     59
     60static inline void arch_local_irq_restore(unsigned long flags)
     61{
     62	unsigned long __tmp1;
     63
     64	__asm__ __volatile__(
     65	"	.set	push						\n"
     66	"	.set	noreorder					\n"
     67	"	.set	noat						\n"
     68#if defined(CONFIG_IRQ_MIPS_CPU)
     69	/*
     70	 * Slow, but doesn't suffer from a relatively unlikely race
     71	 * condition we're having since days 1.
     72	 */
     73	"	beqz	%[flags], 1f					\n"
     74	"	di							\n"
     75	"	ei							\n"
     76	"1:								\n"
     77#else
     78	/*
     79	 * Fast, dangerous.  Life is fun, life is good.
     80	 */
     81	"	mfc0	$1, $12						\n"
     82	"	ins	$1, %[flags], 0, 1				\n"
     83	"	mtc0	$1, $12						\n"
     84#endif
     85	"	" __stringify(__irq_disable_hazard) "			\n"
     86	"	.set	pop						\n"
     87	: [flags] "=r" (__tmp1)
     88	: "0" (flags)
     89	: "memory");
     90}
     91
     92#else
     93/* Functions that require preempt_{dis,en}able() are in mips-atomic.c */
     94void arch_local_irq_disable(void);
     95unsigned long arch_local_irq_save(void);
     96void arch_local_irq_restore(unsigned long flags);
     97#endif /* CONFIG_CPU_HAS_DIEI */
     98
     99static inline void arch_local_irq_enable(void)
    100{
    101	__asm__ __volatile__(
    102	"	.set	push						\n"
    103	"	.set	reorder						\n"
    104	"	.set	noat						\n"
    105#if defined(CONFIG_CPU_HAS_DIEI)
    106	"	ei							\n"
    107#else
    108	"	mfc0	$1,$12						\n"
    109	"	ori	$1,0x1f						\n"
    110	"	xori	$1,0x1e						\n"
    111	"	mtc0	$1,$12						\n"
    112#endif
    113	"	" __stringify(__irq_enable_hazard) "			\n"
    114	"	.set	pop						\n"
    115	: /* no outputs */
    116	: /* no inputs */
    117	: "memory");
    118}
    119
    120static inline unsigned long arch_local_save_flags(void)
    121{
    122	unsigned long flags;
    123
    124	asm __volatile__(
    125	"	.set	push						\n"
    126	"	.set	reorder						\n"
    127	"	mfc0	%[flags], $12					\n"
    128	"	.set	pop						\n"
    129	: [flags] "=r" (flags));
    130
    131	return flags;
    132}
    133
    134
    135static inline int arch_irqs_disabled_flags(unsigned long flags)
    136{
    137	return !(flags & 1);
    138}
    139
    140static inline int arch_irqs_disabled(void)
    141{
    142	return arch_irqs_disabled_flags(arch_local_save_flags());
    143}
    144
    145#endif /* #ifndef __ASSEMBLY__ */
    146
    147/*
    148 * Do the CPU's IRQ-state tracing from assembly code.
    149 */
    150#ifdef CONFIG_TRACE_IRQFLAGS
    151/* Reload some registers clobbered by trace_hardirqs_on */
    152#ifdef CONFIG_64BIT
    153# define TRACE_IRQS_RELOAD_REGS						\
    154	LONG_L	$11, PT_R11(sp);					\
    155	LONG_L	$10, PT_R10(sp);					\
    156	LONG_L	$9, PT_R9(sp);						\
    157	LONG_L	$8, PT_R8(sp);						\
    158	LONG_L	$7, PT_R7(sp);						\
    159	LONG_L	$6, PT_R6(sp);						\
    160	LONG_L	$5, PT_R5(sp);						\
    161	LONG_L	$4, PT_R4(sp);						\
    162	LONG_L	$2, PT_R2(sp)
    163#else
    164# define TRACE_IRQS_RELOAD_REGS						\
    165	LONG_L	$7, PT_R7(sp);						\
    166	LONG_L	$6, PT_R6(sp);						\
    167	LONG_L	$5, PT_R5(sp);						\
    168	LONG_L	$4, PT_R4(sp);						\
    169	LONG_L	$2, PT_R2(sp)
    170#endif
    171# define TRACE_IRQS_ON							\
    172	CLI;	/* make sure trace_hardirqs_on() is called in kernel level */ \
    173	jal	trace_hardirqs_on
    174# define TRACE_IRQS_ON_RELOAD						\
    175	TRACE_IRQS_ON;							\
    176	TRACE_IRQS_RELOAD_REGS
    177# define TRACE_IRQS_OFF							\
    178	jal	trace_hardirqs_off
    179#else
    180# define TRACE_IRQS_ON
    181# define TRACE_IRQS_ON_RELOAD
    182# define TRACE_IRQS_OFF
    183#endif
    184
    185#endif /* _ASM_IRQFLAGS_H */