xref: /linux/arch/arm64/include/asm/daifflags.h (revision 9abdb50cda0ffe33bbb2e40cbad97b32fb7ff892)
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 #define DAIF_ERRCTX		(PSR_I_BIT | PSR_A_BIT)
24 
25 /* mask/save/unmask/restore all exceptions, including interrupts. */
26 static inline void local_daif_mask(void)
27 {
28 	asm volatile(
29 		"msr	daifset, #0xf		// local_daif_mask\n"
30 		:
31 		:
32 		: "memory");
33 	trace_hardirqs_off();
34 }
35 
36 static inline unsigned long local_daif_save(void)
37 {
38 	unsigned long flags;
39 
40 	flags = arch_local_save_flags();
41 
42 	local_daif_mask();
43 
44 	return flags;
45 }
46 
47 static inline void local_daif_unmask(void)
48 {
49 	trace_hardirqs_on();
50 	asm volatile(
51 		"msr	daifclr, #0xf		// local_daif_unmask"
52 		:
53 		:
54 		: "memory");
55 }
56 
57 static inline void local_daif_restore(unsigned long flags)
58 {
59 	if (!arch_irqs_disabled_flags(flags))
60 		trace_hardirqs_on();
61 
62 	arch_local_irq_restore(flags);
63 
64 	if (arch_irqs_disabled_flags(flags))
65 		trace_hardirqs_off();
66 }
67 
68 #endif
69