GNU Linux-libre 4.9.309-gnu1
[releases.git] / arch / x86 / include / asm / irqflags.h
1 #ifndef _X86_IRQFLAGS_H_
2 #define _X86_IRQFLAGS_H_
3
4 #include <asm/processor-flags.h>
5
6 #ifndef __ASSEMBLY__
7
8 #include <asm/nospec-branch.h>
9
10 /* Provide __cpuidle; we can't safely include <linux/cpu.h> */
11 #define __cpuidle __attribute__((__section__(".cpuidle.text")))
12
13 /*
14  * Interrupt control:
15  */
16
17 /* Declaration required for gcc < 4.9 to prevent -Werror=missing-prototypes */
18 extern inline unsigned long native_save_fl(void);
19 extern inline unsigned long native_save_fl(void)
20 {
21         unsigned long flags;
22
23         /*
24          * "=rm" is safe here, because "pop" adjusts the stack before
25          * it evaluates its effective address -- this is part of the
26          * documented behavior of the "pop" instruction.
27          */
28         asm volatile("# __raw_save_flags\n\t"
29                      "pushf ; pop %0"
30                      : "=rm" (flags)
31                      : /* no input */
32                      : "memory");
33
34         return flags;
35 }
36
37 extern inline void native_restore_fl(unsigned long flags);
38 extern inline void native_restore_fl(unsigned long flags)
39 {
40         asm volatile("push %0 ; popf"
41                      : /* no output */
42                      :"g" (flags)
43                      :"memory", "cc");
44 }
45
46 static inline void native_irq_disable(void)
47 {
48         asm volatile("cli": : :"memory");
49 }
50
51 static inline void native_irq_enable(void)
52 {
53         asm volatile("sti": : :"memory");
54 }
55
56 static inline __cpuidle void native_safe_halt(void)
57 {
58         mds_idle_clear_cpu_buffers();
59         asm volatile("sti; hlt": : :"memory");
60 }
61
62 static inline __cpuidle void native_halt(void)
63 {
64         mds_idle_clear_cpu_buffers();
65         asm volatile("hlt": : :"memory");
66 }
67
68 #endif
69
70 #ifdef CONFIG_PARAVIRT
71 #include <asm/paravirt.h>
72 #else
73 #ifndef __ASSEMBLY__
74 #include <linux/types.h>
75
76 static inline notrace unsigned long arch_local_save_flags(void)
77 {
78         return native_save_fl();
79 }
80
81 static inline notrace void arch_local_irq_restore(unsigned long flags)
82 {
83         native_restore_fl(flags);
84 }
85
86 static inline notrace void arch_local_irq_disable(void)
87 {
88         native_irq_disable();
89 }
90
91 static inline notrace void arch_local_irq_enable(void)
92 {
93         native_irq_enable();
94 }
95
96 /*
97  * Used in the idle loop; sti takes one instruction cycle
98  * to complete:
99  */
100 static inline __cpuidle void arch_safe_halt(void)
101 {
102         native_safe_halt();
103 }
104
105 /*
106  * Used when interrupts are already enabled or to
107  * shutdown the processor:
108  */
109 static inline __cpuidle void halt(void)
110 {
111         native_halt();
112 }
113
114 /*
115  * For spinlocks, etc:
116  */
117 static inline notrace unsigned long arch_local_irq_save(void)
118 {
119         unsigned long flags = arch_local_save_flags();
120         arch_local_irq_disable();
121         return flags;
122 }
123 #else
124
125 #define ENABLE_INTERRUPTS(x)    sti
126 #define DISABLE_INTERRUPTS(x)   cli
127
128 #ifdef CONFIG_X86_64
129 #define SWAPGS  swapgs
130 /*
131  * Currently paravirt can't handle swapgs nicely when we
132  * don't have a stack we can rely on (such as a user space
133  * stack).  So we either find a way around these or just fault
134  * and emulate if a guest tries to call swapgs directly.
135  *
136  * Either way, this is a good way to document that we don't
137  * have a reliable stack. x86_64 only.
138  */
139 #define SWAPGS_UNSAFE_STACK     swapgs
140
141 #define PARAVIRT_ADJUST_EXCEPTION_FRAME /*  */
142
143 #define INTERRUPT_RETURN        jmp native_iret
144 #define USERGS_SYSRET64                         \
145         swapgs;                                 \
146         sysretq;
147 #define USERGS_SYSRET32                         \
148         swapgs;                                 \
149         sysretl
150
151 #else
152 #define INTERRUPT_RETURN                iret
153 #define ENABLE_INTERRUPTS_SYSEXIT       sti; sysexit
154 #define GET_CR0_INTO_EAX                movl %cr0, %eax
155 #endif
156
157
158 #endif /* __ASSEMBLY__ */
159 #endif /* CONFIG_PARAVIRT */
160
161 #ifndef __ASSEMBLY__
162 static inline int arch_irqs_disabled_flags(unsigned long flags)
163 {
164         return !(flags & X86_EFLAGS_IF);
165 }
166
167 static inline int arch_irqs_disabled(void)
168 {
169         unsigned long flags = arch_local_save_flags();
170
171         return arch_irqs_disabled_flags(flags);
172 }
173 #endif /* !__ASSEMBLY__ */
174
175 #ifdef __ASSEMBLY__
176 #ifdef CONFIG_TRACE_IRQFLAGS
177 #  define TRACE_IRQS_ON         call trace_hardirqs_on_thunk;
178 #  define TRACE_IRQS_OFF        call trace_hardirqs_off_thunk;
179 #else
180 #  define TRACE_IRQS_ON
181 #  define TRACE_IRQS_OFF
182 #endif
183 #ifdef CONFIG_DEBUG_LOCK_ALLOC
184 #  ifdef CONFIG_X86_64
185 #    define LOCKDEP_SYS_EXIT            call lockdep_sys_exit_thunk
186 #    define LOCKDEP_SYS_EXIT_IRQ \
187         TRACE_IRQS_ON; \
188         sti; \
189         call lockdep_sys_exit_thunk; \
190         cli; \
191         TRACE_IRQS_OFF;
192 #  else
193 #    define LOCKDEP_SYS_EXIT \
194         pushl %eax;                             \
195         pushl %ecx;                             \
196         pushl %edx;                             \
197         call lockdep_sys_exit;                  \
198         popl %edx;                              \
199         popl %ecx;                              \
200         popl %eax;
201 #    define LOCKDEP_SYS_EXIT_IRQ
202 #  endif
203 #else
204 #  define LOCKDEP_SYS_EXIT
205 #  define LOCKDEP_SYS_EXIT_IRQ
206 #endif
207 #endif /* __ASSEMBLY__ */
208
209 #endif