GNU Linux-libre 4.19.286-gnu1
[releases.git] / arch / arm64 / include / asm / daifflags.h
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