aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-x86
diff options
context:
space:
mode:
authorGlauber de Oliveira Costa <gcosta@redhat.com>2008-01-30 07:30:33 -0500
committerIngo Molnar <mingo@elte.hu>2008-01-30 07:30:33 -0500
commit6abcd98ffafbff81f0bfd7ee1d129e634af13245 (patch)
tree8226ad9c29998a5596d351bf8b4eab4dfccaf898 /include/asm-x86
parent416b72182ac3f3f4931ed17d0256b1d805d1b553 (diff)
x86: irqflags consolidation
This patch consolidates the irqflags include files containing common paravirt definitions. The native definition for interrupt handling, halt, and such, are the same for 32 and 64 bit, and they are kept in irqflags.h. the differences are split in the arch-specific files. The syscall function, irq_enable_sysexit, has a very specific i386 naming, and its name is then changed to a more general one. Signed-off-by: Glauber de Oliveira Costa <gcosta@redhat.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org> Acked-by: Jeremy Fitzhardinge <jeremy@xensource.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'include/asm-x86')
-rw-r--r--include/asm-x86/irqflags.h246
-rw-r--r--include/asm-x86/irqflags_32.h195
-rw-r--r--include/asm-x86/irqflags_64.h174
-rw-r--r--include/asm-x86/paravirt.h9
4 files changed, 248 insertions, 376 deletions
diff --git a/include/asm-x86/irqflags.h b/include/asm-x86/irqflags.h
index 1b695ff52687..92021c1ffa3a 100644
--- a/include/asm-x86/irqflags.h
+++ b/include/asm-x86/irqflags.h
@@ -1,5 +1,245 @@
1#ifdef CONFIG_X86_32 1#ifndef _X86_IRQFLAGS_H_
2# include "irqflags_32.h" 2#define _X86_IRQFLAGS_H_
3
4#include <asm/processor-flags.h>
5
6#ifndef __ASSEMBLY__
7/*
8 * Interrupt control:
9 */
10
11static inline unsigned long native_save_fl(void)
12{
13 unsigned long flags;
14
15 __asm__ __volatile__(
16 "# __raw_save_flags\n\t"
17 "pushf ; pop %0"
18 : "=g" (flags)
19 : /* no input */
20 : "memory"
21 );
22
23 return flags;
24}
25
26static inline void native_restore_fl(unsigned long flags)
27{
28 __asm__ __volatile__(
29 "push %0 ; popf"
30 : /* no output */
31 :"g" (flags)
32 :"memory", "cc"
33 );
34}
35
36static inline void native_irq_disable(void)
37{
38 asm volatile("cli": : :"memory");
39}
40
41static inline void native_irq_enable(void)
42{
43 asm volatile("sti": : :"memory");
44}
45
46static inline void native_safe_halt(void)
47{
48 asm volatile("sti; hlt": : :"memory");
49}
50
51static inline void native_halt(void)
52{
53 asm volatile("hlt": : :"memory");
54}
55
56#endif
57
58#ifdef CONFIG_PARAVIRT
59#include <asm/paravirt.h>
60#else
61#ifndef __ASSEMBLY__
62
63static inline unsigned long __raw_local_save_flags(void)
64{
65 return native_save_fl();
66}
67
68static inline void raw_local_irq_restore(unsigned long flags)
69{
70 native_restore_fl(flags);
71}
72
73static inline void raw_local_irq_disable(void)
74{
75 native_irq_disable();
76}
77
78static inline void raw_local_irq_enable(void)
79{
80 native_irq_enable();
81}
82
83/*
84 * Used in the idle loop; sti takes one instruction cycle
85 * to complete:
86 */
87static inline void raw_safe_halt(void)
88{
89 native_safe_halt();
90}
91
92/*
93 * Used when interrupts are already enabled or to
94 * shutdown the processor:
95 */
96static inline void halt(void)
97{
98 native_halt();
99}
100
101/*
102 * For spinlocks, etc:
103 */
104static inline unsigned long __raw_local_irq_save(void)
105{
106 unsigned long flags = __raw_local_save_flags();
107
108 raw_local_irq_disable();
109
110 return flags;
111}
112#else
113
114#define ENABLE_INTERRUPTS(x) sti
115#define DISABLE_INTERRUPTS(x) cli
116
117#ifdef CONFIG_X86_64
118#define INTERRUPT_RETURN iretq
119#define ENABLE_INTERRUPTS_SYSCALL_RET \
120 movq %gs:pda_oldrsp, %rsp; \
121 swapgs; \
122 sysretq;
123#else
124#define INTERRUPT_RETURN iret
125#define ENABLE_INTERRUPTS_SYSCALL_RET sti; sysexit
126#define GET_CR0_INTO_EAX movl %cr0, %eax
127#endif
128
129
130#endif /* __ASSEMBLY__ */
131#endif /* CONFIG_PARAVIRT */
132
133#ifndef __ASSEMBLY__
134#define raw_local_save_flags(flags) \
135 do { (flags) = __raw_local_save_flags(); } while (0)
136
137#define raw_local_irq_save(flags) \
138 do { (flags) = __raw_local_irq_save(); } while (0)
139
140static inline int raw_irqs_disabled_flags(unsigned long flags)
141{
142 return !(flags & X86_EFLAGS_IF);
143}
144
145static inline int raw_irqs_disabled(void)
146{
147 unsigned long flags = __raw_local_save_flags();
148
149 return raw_irqs_disabled_flags(flags);
150}
151
152/*
153 * makes the traced hardirq state match with the machine state
154 *
155 * should be a rarely used function, only in places where its
156 * otherwise impossible to know the irq state, like in traps.
157 */
158static inline void trace_hardirqs_fixup_flags(unsigned long flags)
159{
160 if (raw_irqs_disabled_flags(flags))
161 trace_hardirqs_off();
162 else
163 trace_hardirqs_on();
164}
165
166static inline void trace_hardirqs_fixup(void)
167{
168 unsigned long flags = __raw_local_save_flags();
169
170 trace_hardirqs_fixup_flags(flags);
171}
172
3#else 173#else
4# include "irqflags_64.h" 174
175#ifdef CONFIG_X86_64
176/*
177 * Currently paravirt can't handle swapgs nicely when we
178 * don't have a stack we can rely on (such as a user space
179 * stack). So we either find a way around these or just fault
180 * and emulate if a guest tries to call swapgs directly.
181 *
182 * Either way, this is a good way to document that we don't
183 * have a reliable stack. x86_64 only.
184 */
185#define SWAPGS_UNSAFE_STACK swapgs
186#define ARCH_TRACE_IRQS_ON call trace_hardirqs_on_thunk
187#define ARCH_TRACE_IRQS_OFF call trace_hardirqs_off_thunk
188#define ARCH_LOCKDEP_SYS_EXIT call lockdep_sys_exit_thunk
189#define ARCH_LOCKDEP_SYS_EXIT_IRQ \
190 TRACE_IRQS_ON; \
191 sti; \
192 SAVE_REST; \
193 LOCKDEP_SYS_EXIT; \
194 RESTORE_REST; \
195 cli; \
196 TRACE_IRQS_OFF;
197
198#else
199#define ARCH_TRACE_IRQS_ON \
200 pushl %eax; \
201 pushl %ecx; \
202 pushl %edx; \
203 call trace_hardirqs_on; \
204 popl %edx; \
205 popl %ecx; \
206 popl %eax;
207
208#define ARCH_TRACE_IRQS_OFF \
209 pushl %eax; \
210 pushl %ecx; \
211 pushl %edx; \
212 call trace_hardirqs_off; \
213 popl %edx; \
214 popl %ecx; \
215 popl %eax;
216
217#define ARCH_LOCKDEP_SYS_EXIT \
218 pushl %eax; \
219 pushl %ecx; \
220 pushl %edx; \
221 call lockdep_sys_exit; \
222 popl %edx; \
223 popl %ecx; \
224 popl %eax;
225
226#define ARCH_LOCKDEP_SYS_EXIT_IRQ
227#endif
228
229#ifdef CONFIG_TRACE_IRQFLAGS
230# define TRACE_IRQS_ON ARCH_TRACE_IRQS_ON
231# define TRACE_IRQS_OFF ARCH_TRACE_IRQS_OFF
232#else
233# define TRACE_IRQS_ON
234# define TRACE_IRQS_OFF
235#endif
236#ifdef CONFIG_DEBUG_LOCK_ALLOC
237# define LOCKDEP_SYS_EXIT ARCH_LOCKDEP_SYS_EXIT
238# define LOCKDEP_SYS_EXIT_IRQ ARCH_LOCKDEP_SYS_EXIT_IRQ
239# else
240# define LOCKDEP_SYS_EXIT
241# define LOCKDEP_SYS_EXIT_IRQ
242# endif
243
244#endif /* __ASSEMBLY__ */
5#endif 245#endif
diff --git a/include/asm-x86/irqflags_32.h b/include/asm-x86/irqflags_32.h
deleted file mode 100644
index 98b21b9bdce8..000000000000
--- a/include/asm-x86/irqflags_32.h
+++ /dev/null
@@ -1,195 +0,0 @@
1/*
2 * IRQ flags handling
3 *
4 * This file gets included from lowlevel asm headers too, to provide
5 * wrapped versions of the local_irq_*() APIs, based on the
6 * raw_local_irq_*() functions from the lowlevel headers.
7 */
8#ifndef _ASM_IRQFLAGS_H
9#define _ASM_IRQFLAGS_H
10#include <asm/processor-flags.h>
11
12#ifndef __ASSEMBLY__
13static inline unsigned long native_save_fl(void)
14{
15 unsigned long f;
16 asm volatile("pushfl ; popl %0":"=g" (f): /* no input */);
17 return f;
18}
19
20static inline void native_restore_fl(unsigned long f)
21{
22 asm volatile("pushl %0 ; popfl": /* no output */
23 :"g" (f)
24 :"memory", "cc");
25}
26
27static inline void native_irq_disable(void)
28{
29 asm volatile("cli": : :"memory");
30}
31
32static inline void native_irq_enable(void)
33{
34 asm volatile("sti": : :"memory");
35}
36
37static inline void native_safe_halt(void)
38{
39 asm volatile("sti; hlt": : :"memory");
40}
41
42static inline void native_halt(void)
43{
44 asm volatile("hlt": : :"memory");
45}
46#endif /* __ASSEMBLY__ */
47
48#ifdef CONFIG_PARAVIRT
49#include <asm/paravirt.h>
50#else
51#ifndef __ASSEMBLY__
52
53static inline unsigned long __raw_local_save_flags(void)
54{
55 return native_save_fl();
56}
57
58static inline void raw_local_irq_restore(unsigned long flags)
59{
60 native_restore_fl(flags);
61}
62
63static inline void raw_local_irq_disable(void)
64{
65 native_irq_disable();
66}
67
68static inline void raw_local_irq_enable(void)
69{
70 native_irq_enable();
71}
72
73/*
74 * Used in the idle loop; sti takes one instruction cycle
75 * to complete:
76 */
77static inline void raw_safe_halt(void)
78{
79 native_safe_halt();
80}
81
82/*
83 * Used when interrupts are already enabled or to
84 * shutdown the processor:
85 */
86static inline void halt(void)
87{
88 native_halt();
89}
90
91/*
92 * For spinlocks, etc:
93 */
94static inline unsigned long __raw_local_irq_save(void)
95{
96 unsigned long flags = __raw_local_save_flags();
97
98 raw_local_irq_disable();
99
100 return flags;
101}
102
103#else
104#define DISABLE_INTERRUPTS(clobbers) cli
105#define ENABLE_INTERRUPTS(clobbers) sti
106#define ENABLE_INTERRUPTS_SYSEXIT sti; sysexit
107#define INTERRUPT_RETURN iret
108#define GET_CR0_INTO_EAX movl %cr0, %eax
109#endif /* __ASSEMBLY__ */
110#endif /* CONFIG_PARAVIRT */
111
112#ifndef __ASSEMBLY__
113#define raw_local_save_flags(flags) \
114 do { (flags) = __raw_local_save_flags(); } while (0)
115
116#define raw_local_irq_save(flags) \
117 do { (flags) = __raw_local_irq_save(); } while (0)
118
119static inline int raw_irqs_disabled_flags(unsigned long flags)
120{
121 return !(flags & X86_EFLAGS_IF);
122}
123
124static inline int raw_irqs_disabled(void)
125{
126 unsigned long flags = __raw_local_save_flags();
127
128 return raw_irqs_disabled_flags(flags);
129}
130
131/*
132 * makes the traced hardirq state match with the machine state
133 *
134 * should be a rarely used function, only in places where its
135 * otherwise impossible to know the irq state, like in traps.
136 */
137static inline void trace_hardirqs_fixup_flags(unsigned long flags)
138{
139 if (raw_irqs_disabled_flags(flags))
140 trace_hardirqs_off();
141 else
142 trace_hardirqs_on();
143}
144
145static inline void trace_hardirqs_fixup(void)
146{
147 unsigned long flags = __raw_local_save_flags();
148
149 trace_hardirqs_fixup_flags(flags);
150}
151#endif /* __ASSEMBLY__ */
152
153/*
154 * Do the CPU's IRQ-state tracing from assembly code. We call a
155 * C function, so save all the C-clobbered registers:
156 */
157#ifdef CONFIG_TRACE_IRQFLAGS
158
159# define TRACE_IRQS_ON \
160 pushl %eax; \
161 pushl %ecx; \
162 pushl %edx; \
163 call trace_hardirqs_on; \
164 popl %edx; \
165 popl %ecx; \
166 popl %eax;
167
168# define TRACE_IRQS_OFF \
169 pushl %eax; \
170 pushl %ecx; \
171 pushl %edx; \
172 call trace_hardirqs_off; \
173 popl %edx; \
174 popl %ecx; \
175 popl %eax;
176
177#else
178# define TRACE_IRQS_ON
179# define TRACE_IRQS_OFF
180#endif
181
182#ifdef CONFIG_DEBUG_LOCK_ALLOC
183# define LOCKDEP_SYS_EXIT \
184 pushl %eax; \
185 pushl %ecx; \
186 pushl %edx; \
187 call lockdep_sys_exit; \
188 popl %edx; \
189 popl %ecx; \
190 popl %eax;
191#else
192# define LOCKDEP_SYS_EXIT
193#endif
194
195#endif
diff --git a/include/asm-x86/irqflags_64.h b/include/asm-x86/irqflags_64.h
deleted file mode 100644
index 38c07db733cf..000000000000
--- a/include/asm-x86/irqflags_64.h
+++ /dev/null
@@ -1,174 +0,0 @@
1/*
2 * IRQ flags handling
3 *
4 * This file gets included from lowlevel asm headers too, to provide
5 * wrapped versions of the local_irq_*() APIs, based on the
6 * raw_local_irq_*() functions from the lowlevel headers.
7 */
8#ifndef _ASM_IRQFLAGS_H
9#define _ASM_IRQFLAGS_H
10#include <asm/processor-flags.h>
11
12#ifndef __ASSEMBLY__
13/*
14 * Interrupt control:
15 */
16
17static inline unsigned long __raw_local_save_flags(void)
18{
19 unsigned long flags;
20
21 __asm__ __volatile__(
22 "# __raw_save_flags\n\t"
23 "pushfq ; popq %q0"
24 : "=g" (flags)
25 : /* no input */
26 : "memory"
27 );
28
29 return flags;
30}
31
32#define raw_local_save_flags(flags) \
33 do { (flags) = __raw_local_save_flags(); } while (0)
34
35static inline void raw_local_irq_restore(unsigned long flags)
36{
37 __asm__ __volatile__(
38 "pushq %0 ; popfq"
39 : /* no output */
40 :"g" (flags)
41 :"memory", "cc"
42 );
43}
44
45#ifdef CONFIG_X86_VSMP
46
47/*
48 * Interrupt control for the VSMP architecture:
49 */
50
51static inline void raw_local_irq_disable(void)
52{
53 unsigned long flags = __raw_local_save_flags();
54
55 raw_local_irq_restore((flags & ~X86_EFLAGS_IF) | X86_EFLAGS_AC);
56}
57
58static inline void raw_local_irq_enable(void)
59{
60 unsigned long flags = __raw_local_save_flags();
61
62 raw_local_irq_restore((flags | X86_EFLAGS_IF) & (~X86_EFLAGS_AC));
63}
64
65static inline int raw_irqs_disabled_flags(unsigned long flags)
66{
67 return !(flags & X86_EFLAGS_IF) || (flags & X86_EFLAGS_AC);
68}
69
70#else /* CONFIG_X86_VSMP */
71
72static inline void raw_local_irq_disable(void)
73{
74 __asm__ __volatile__("cli" : : : "memory");
75}
76
77static inline void raw_local_irq_enable(void)
78{
79 __asm__ __volatile__("sti" : : : "memory");
80}
81
82static inline int raw_irqs_disabled_flags(unsigned long flags)
83{
84 return !(flags & X86_EFLAGS_IF);
85}
86
87#endif
88
89/*
90 * For spinlocks, etc.:
91 */
92
93static inline unsigned long __raw_local_irq_save(void)
94{
95 unsigned long flags = __raw_local_save_flags();
96
97 raw_local_irq_disable();
98
99 return flags;
100}
101
102#define raw_local_irq_save(flags) \
103 do { (flags) = __raw_local_irq_save(); } while (0)
104
105static inline int raw_irqs_disabled(void)
106{
107 unsigned long flags = __raw_local_save_flags();
108
109 return raw_irqs_disabled_flags(flags);
110}
111
112/*
113 * makes the traced hardirq state match with the machine state
114 *
115 * should be a rarely used function, only in places where its
116 * otherwise impossible to know the irq state, like in traps.
117 */
118static inline void trace_hardirqs_fixup_flags(unsigned long flags)
119{
120 if (raw_irqs_disabled_flags(flags))
121 trace_hardirqs_off();
122 else
123 trace_hardirqs_on();
124}
125
126static inline void trace_hardirqs_fixup(void)
127{
128 unsigned long flags = __raw_local_save_flags();
129
130 trace_hardirqs_fixup_flags(flags);
131}
132/*
133 * Used in the idle loop; sti takes one instruction cycle
134 * to complete:
135 */
136static inline void raw_safe_halt(void)
137{
138 __asm__ __volatile__("sti; hlt" : : : "memory");
139}
140
141/*
142 * Used when interrupts are already enabled or to
143 * shutdown the processor:
144 */
145static inline void halt(void)
146{
147 __asm__ __volatile__("hlt": : :"memory");
148}
149
150#else /* __ASSEMBLY__: */
151# ifdef CONFIG_TRACE_IRQFLAGS
152# define TRACE_IRQS_ON call trace_hardirqs_on_thunk
153# define TRACE_IRQS_OFF call trace_hardirqs_off_thunk
154# else
155# define TRACE_IRQS_ON
156# define TRACE_IRQS_OFF
157# endif
158# ifdef CONFIG_DEBUG_LOCK_ALLOC
159# define LOCKDEP_SYS_EXIT call lockdep_sys_exit_thunk
160# define LOCKDEP_SYS_EXIT_IRQ \
161 TRACE_IRQS_ON; \
162 sti; \
163 SAVE_REST; \
164 LOCKDEP_SYS_EXIT; \
165 RESTORE_REST; \
166 cli; \
167 TRACE_IRQS_OFF;
168# else
169# define LOCKDEP_SYS_EXIT
170# define LOCKDEP_SYS_EXIT_IRQ
171# endif
172#endif
173
174#endif
diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h
index 19fd3e67b08c..be7b934f6c54 100644
--- a/include/asm-x86/paravirt.h
+++ b/include/asm-x86/paravirt.h
@@ -121,7 +121,7 @@ struct pv_cpu_ops {
121 u64 (*read_pmc)(void); 121 u64 (*read_pmc)(void);
122 122
123 /* These two are jmp to, not actually called. */ 123 /* These two are jmp to, not actually called. */
124 void (*irq_enable_sysexit)(void); 124 void (*irq_enable_syscall_ret)(void);
125 void (*iret)(void); 125 void (*iret)(void);
126 126
127 struct pv_lazy_ops lazy_mode; 127 struct pv_lazy_ops lazy_mode;
@@ -1138,9 +1138,10 @@ static inline unsigned long __raw_local_irq_save(void)
1138 call *%cs:pv_irq_ops+PV_IRQ_irq_enable; \ 1138 call *%cs:pv_irq_ops+PV_IRQ_irq_enable; \
1139 popl %edx; popl %ecx; popl %eax) 1139 popl %edx; popl %ecx; popl %eax)
1140 1140
1141#define ENABLE_INTERRUPTS_SYSEXIT \ 1141#define ENABLE_INTERRUPTS_SYSCALL_RET \
1142 PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_irq_enable_sysexit), CLBR_NONE,\ 1142 PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_irq_enable_syscall_ret),\
1143 jmp *%cs:pv_cpu_ops+PV_CPU_irq_enable_sysexit) 1143 CLBR_NONE, \
1144 jmp *%cs:pv_cpu_ops+PV_CPU_irq_enable_syscall_ret)
1144 1145
1145#define GET_CR0_INTO_EAX \ 1146#define GET_CR0_INTO_EAX \
1146 push %ecx; push %edx; \ 1147 push %ecx; push %edx; \