~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/arm64/include/asm/irqflags.h

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /* SPDX-License-Identifier: GPL-2.0-only */
  2 /*
  3  * Copyright (C) 2012 ARM Ltd.
  4  */
  5 #ifndef __ASM_IRQFLAGS_H
  6 #define __ASM_IRQFLAGS_H
  7 
  8 #include <asm/barrier.h>
  9 #include <asm/ptrace.h>
 10 #include <asm/sysreg.h>
 11 
 12 /*
 13  * Aarch64 has flags for masking: Debug, Asynchronous (serror), Interrupts and
 14  * FIQ exceptions, in the 'daif' register. We mask and unmask them in 'daif'
 15  * order:
 16  * Masking debug exceptions causes all other exceptions to be masked too/
 17  * Masking SError masks IRQ/FIQ, but not debug exceptions. IRQ and FIQ are
 18  * always masked and unmasked together, and have no side effects for other
 19  * flags. Keeping to this order makes it easier for entry.S to know which
 20  * exceptions should be unmasked.
 21  */
 22 
 23 static __always_inline void __daif_local_irq_enable(void)
 24 {
 25         barrier();
 26         asm volatile("msr daifclr, #3");
 27         barrier();
 28 }
 29 
 30 static __always_inline void __pmr_local_irq_enable(void)
 31 {
 32         if (IS_ENABLED(CONFIG_ARM64_DEBUG_PRIORITY_MASKING)) {
 33                 u32 pmr = read_sysreg_s(SYS_ICC_PMR_EL1);
 34                 WARN_ON_ONCE(pmr != GIC_PRIO_IRQON && pmr != GIC_PRIO_IRQOFF);
 35         }
 36 
 37         barrier();
 38         write_sysreg_s(GIC_PRIO_IRQON, SYS_ICC_PMR_EL1);
 39         pmr_sync();
 40         barrier();
 41 }
 42 
 43 static inline void arch_local_irq_enable(void)
 44 {
 45         if (system_uses_irq_prio_masking()) {
 46                 __pmr_local_irq_enable();
 47         } else {
 48                 __daif_local_irq_enable();
 49         }
 50 }
 51 
 52 static __always_inline void __daif_local_irq_disable(void)
 53 {
 54         barrier();
 55         asm volatile("msr daifset, #3");
 56         barrier();
 57 }
 58 
 59 static __always_inline void __pmr_local_irq_disable(void)
 60 {
 61         if (IS_ENABLED(CONFIG_ARM64_DEBUG_PRIORITY_MASKING)) {
 62                 u32 pmr = read_sysreg_s(SYS_ICC_PMR_EL1);
 63                 WARN_ON_ONCE(pmr != GIC_PRIO_IRQON && pmr != GIC_PRIO_IRQOFF);
 64         }
 65 
 66         barrier();
 67         write_sysreg_s(GIC_PRIO_IRQOFF, SYS_ICC_PMR_EL1);
 68         barrier();
 69 }
 70 
 71 static inline void arch_local_irq_disable(void)
 72 {
 73         if (system_uses_irq_prio_masking()) {
 74                 __pmr_local_irq_disable();
 75         } else {
 76                 __daif_local_irq_disable();
 77         }
 78 }
 79 
 80 static __always_inline unsigned long __daif_local_save_flags(void)
 81 {
 82         return read_sysreg(daif);
 83 }
 84 
 85 static __always_inline unsigned long __pmr_local_save_flags(void)
 86 {
 87         return read_sysreg_s(SYS_ICC_PMR_EL1);
 88 }
 89 
 90 /*
 91  * Save the current interrupt enable state.
 92  */
 93 static inline unsigned long arch_local_save_flags(void)
 94 {
 95         if (system_uses_irq_prio_masking()) {
 96                 return __pmr_local_save_flags();
 97         } else {
 98                 return __daif_local_save_flags();
 99         }
100 }
101 
102 static __always_inline bool __daif_irqs_disabled_flags(unsigned long flags)
103 {
104         return flags & PSR_I_BIT;
105 }
106 
107 static __always_inline bool __pmr_irqs_disabled_flags(unsigned long flags)
108 {
109         return flags != GIC_PRIO_IRQON;
110 }
111 
112 static inline bool arch_irqs_disabled_flags(unsigned long flags)
113 {
114         if (system_uses_irq_prio_masking()) {
115                 return __pmr_irqs_disabled_flags(flags);
116         } else {
117                 return __daif_irqs_disabled_flags(flags);
118         }
119 }
120 
121 static __always_inline bool __daif_irqs_disabled(void)
122 {
123         return __daif_irqs_disabled_flags(__daif_local_save_flags());
124 }
125 
126 static __always_inline bool __pmr_irqs_disabled(void)
127 {
128         return __pmr_irqs_disabled_flags(__pmr_local_save_flags());
129 }
130 
131 static inline bool arch_irqs_disabled(void)
132 {
133         if (system_uses_irq_prio_masking()) {
134                 return __pmr_irqs_disabled();
135         } else {
136                 return __daif_irqs_disabled();
137         }
138 }
139 
140 static __always_inline unsigned long __daif_local_irq_save(void)
141 {
142         unsigned long flags = __daif_local_save_flags();
143 
144         __daif_local_irq_disable();
145 
146         return flags;
147 }
148 
149 static __always_inline unsigned long __pmr_local_irq_save(void)
150 {
151         unsigned long flags = __pmr_local_save_flags();
152 
153         /*
154          * There are too many states with IRQs disabled, just keep the current
155          * state if interrupts are already disabled/masked.
156          */
157         if (!__pmr_irqs_disabled_flags(flags))
158                 __pmr_local_irq_disable();
159 
160         return flags;
161 }
162 
163 static inline unsigned long arch_local_irq_save(void)
164 {
165         if (system_uses_irq_prio_masking()) {
166                 return __pmr_local_irq_save();
167         } else {
168                 return __daif_local_irq_save();
169         }
170 }
171 
172 static __always_inline void __daif_local_irq_restore(unsigned long flags)
173 {
174         barrier();
175         write_sysreg(flags, daif);
176         barrier();
177 }
178 
179 static __always_inline void __pmr_local_irq_restore(unsigned long flags)
180 {
181         barrier();
182         write_sysreg_s(flags, SYS_ICC_PMR_EL1);
183         pmr_sync();
184         barrier();
185 }
186 
187 /*
188  * restore saved IRQ state
189  */
190 static inline void arch_local_irq_restore(unsigned long flags)
191 {
192         if (system_uses_irq_prio_masking()) {
193                 __pmr_local_irq_restore(flags);
194         } else {
195                 __daif_local_irq_restore(flags);
196         }
197 }
198 
199 #endif /* __ASM_IRQFLAGS_H */
200 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php