xref: /openbmc/linux/arch/arm64/include/asm/daifflags.h (revision 09bae3b6)
1 /*
2  * Copyright (C) 2017 ARM Ltd.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
15  */
16 #ifndef __ASM_DAIFFLAGS_H
17 #define __ASM_DAIFFLAGS_H
18 
19 #include <linux/irqflags.h>
20 
21 #define DAIF_PROCCTX		0
22 #define DAIF_PROCCTX_NOIRQ	PSR_I_BIT
23 
24 /* mask/save/unmask/restore all exceptions, including interrupts. */
25 static inline void local_daif_mask(void)
26 {
27 	asm volatile(
28 		"msr	daifset, #0xf		// local_daif_mask\n"
29 		:
30 		:
31 		: "memory");
32 	trace_hardirqs_off();
33 }
34 
35 static inline unsigned long local_daif_save(void)
36 {
37 	unsigned long flags;
38 
39 	asm volatile(
40 		"mrs	%0, daif		// local_daif_save\n"
41 		: "=r" (flags)
42 		:
43 		: "memory");
44 	local_daif_mask();
45 
46 	return flags;
47 }
48 
49 static inline void local_daif_unmask(void)
50 {
51 	trace_hardirqs_on();
52 	asm volatile(
53 		"msr	daifclr, #0xf		// local_daif_unmask"
54 		:
55 		:
56 		: "memory");
57 }
58 
59 static inline void local_daif_restore(unsigned long flags)
60 {
61 	if (!arch_irqs_disabled_flags(flags))
62 		trace_hardirqs_on();
63 	asm volatile(
64 		"msr	daif, %0		// local_daif_restore"
65 		:
66 		: "r" (flags)
67 		: "memory");
68 	if (arch_irqs_disabled_flags(flags))
69 		trace_hardirqs_off();
70 }
71 
72 #endif
73