arch/x86/include/asm/irqflags.h
changeset 0 aa628870c1d3
equal deleted inserted replaced
-1:000000000000 0:aa628870c1d3
       
     1 #ifndef _X86_IRQFLAGS_H_
       
     2 #define _X86_IRQFLAGS_H_
       
     3 
       
     4 #include <asm/processor-flags.h>
       
     5 
       
     6 #ifndef __ASSEMBLY__
       
     7 /*
       
     8  * Interrupt control:
       
     9  */
       
    10 
       
    11 static inline unsigned long native_save_fl(void)
       
    12 {
       
    13 	unsigned long flags;
       
    14 
       
    15 	asm volatile("# __raw_save_flags\n\t"
       
    16 		     "pushf ; pop %0"
       
    17 		     : "=g" (flags)
       
    18 		     : /* no input */
       
    19 		     : "memory");
       
    20 
       
    21 	return flags;
       
    22 }
       
    23 
       
    24 static inline void native_restore_fl(unsigned long flags)
       
    25 {
       
    26 	asm volatile("push %0 ; popf"
       
    27 		     : /* no output */
       
    28 		     :"g" (flags)
       
    29 		     :"memory", "cc");
       
    30 }
       
    31 
       
    32 static inline void native_irq_disable(void)
       
    33 {
       
    34 	asm volatile("cli": : :"memory");
       
    35 }
       
    36 
       
    37 static inline void native_irq_enable(void)
       
    38 {
       
    39 	asm volatile("sti": : :"memory");
       
    40 }
       
    41 
       
    42 static inline void native_safe_halt(void)
       
    43 {
       
    44 	asm volatile("sti; hlt": : :"memory");
       
    45 }
       
    46 
       
    47 static inline void native_halt(void)
       
    48 {
       
    49 	asm volatile("hlt": : :"memory");
       
    50 }
       
    51 
       
    52 #endif
       
    53 
       
    54 #ifdef CONFIG_PARAVIRT
       
    55 #include <asm/paravirt.h>
       
    56 #else
       
    57 #ifndef __ASSEMBLY__
       
    58 
       
    59 static inline unsigned long __raw_local_save_flags(void)
       
    60 {
       
    61 	return native_save_fl();
       
    62 }
       
    63 
       
    64 static inline void raw_local_irq_restore(unsigned long flags)
       
    65 {
       
    66 	native_restore_fl(flags);
       
    67 }
       
    68 
       
    69 static inline void raw_local_irq_disable(void)
       
    70 {
       
    71 	native_irq_disable();
       
    72 }
       
    73 
       
    74 static inline void raw_local_irq_enable(void)
       
    75 {
       
    76 	native_irq_enable();
       
    77 }
       
    78 
       
    79 /*
       
    80  * Used in the idle loop; sti takes one instruction cycle
       
    81  * to complete:
       
    82  */
       
    83 static inline void raw_safe_halt(void)
       
    84 {
       
    85 	native_safe_halt();
       
    86 }
       
    87 
       
    88 /*
       
    89  * Used when interrupts are already enabled or to
       
    90  * shutdown the processor:
       
    91  */
       
    92 static inline void halt(void)
       
    93 {
       
    94 	native_halt();
       
    95 }
       
    96 
       
    97 /*
       
    98  * For spinlocks, etc:
       
    99  */
       
   100 static inline unsigned long __raw_local_irq_save(void)
       
   101 {
       
   102 	unsigned long flags = __raw_local_save_flags();
       
   103 
       
   104 	raw_local_irq_disable();
       
   105 
       
   106 	return flags;
       
   107 }
       
   108 #else
       
   109 
       
   110 #define ENABLE_INTERRUPTS(x)	sti
       
   111 #define DISABLE_INTERRUPTS(x)	cli
       
   112 
       
   113 #ifdef CONFIG_X86_64
       
   114 #define SWAPGS	swapgs
       
   115 /*
       
   116  * Currently paravirt can't handle swapgs nicely when we
       
   117  * don't have a stack we can rely on (such as a user space
       
   118  * stack).  So we either find a way around these or just fault
       
   119  * and emulate if a guest tries to call swapgs directly.
       
   120  *
       
   121  * Either way, this is a good way to document that we don't
       
   122  * have a reliable stack. x86_64 only.
       
   123  */
       
   124 #define SWAPGS_UNSAFE_STACK	swapgs
       
   125 
       
   126 #define PARAVIRT_ADJUST_EXCEPTION_FRAME	/*  */
       
   127 
       
   128 #define INTERRUPT_RETURN	iretq
       
   129 #define USERGS_SYSRET64				\
       
   130 	swapgs;					\
       
   131 	sysretq;
       
   132 #define USERGS_SYSRET32				\
       
   133 	swapgs;					\
       
   134 	sysretl
       
   135 #define ENABLE_INTERRUPTS_SYSEXIT32		\
       
   136 	swapgs;					\
       
   137 	sti;					\
       
   138 	sysexit
       
   139 
       
   140 #else
       
   141 #define INTERRUPT_RETURN		iret
       
   142 #define ENABLE_INTERRUPTS_SYSEXIT	sti; sysexit
       
   143 #define GET_CR0_INTO_EAX		movl %cr0, %eax
       
   144 #endif
       
   145 
       
   146 
       
   147 #endif /* __ASSEMBLY__ */
       
   148 #endif /* CONFIG_PARAVIRT */
       
   149 
       
   150 #ifndef __ASSEMBLY__
       
   151 #define raw_local_save_flags(flags)				\
       
   152 	do { (flags) = __raw_local_save_flags(); } while (0)
       
   153 
       
   154 #define raw_local_irq_save(flags)				\
       
   155 	do { (flags) = __raw_local_irq_save(); } while (0)
       
   156 
       
   157 static inline int raw_irqs_disabled_flags(unsigned long flags)
       
   158 {
       
   159 	return !(flags & X86_EFLAGS_IF);
       
   160 }
       
   161 
       
   162 static inline int raw_irqs_disabled(void)
       
   163 {
       
   164 	unsigned long flags = __raw_local_save_flags();
       
   165 
       
   166 	return raw_irqs_disabled_flags(flags);
       
   167 }
       
   168 
       
   169 #else
       
   170 
       
   171 #ifdef CONFIG_X86_64
       
   172 #define ARCH_LOCKDEP_SYS_EXIT		call lockdep_sys_exit_thunk
       
   173 #define ARCH_LOCKDEP_SYS_EXIT_IRQ	\
       
   174 	TRACE_IRQS_ON; \
       
   175 	sti; \
       
   176 	SAVE_REST; \
       
   177 	LOCKDEP_SYS_EXIT; \
       
   178 	RESTORE_REST; \
       
   179 	cli; \
       
   180 	TRACE_IRQS_OFF;
       
   181 
       
   182 #else
       
   183 #define ARCH_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 
       
   192 #define ARCH_LOCKDEP_SYS_EXIT_IRQ
       
   193 #endif
       
   194 
       
   195 #ifdef CONFIG_TRACE_IRQFLAGS
       
   196 #  define TRACE_IRQS_ON		call trace_hardirqs_on_thunk;
       
   197 #  define TRACE_IRQS_OFF	call trace_hardirqs_off_thunk;
       
   198 #else
       
   199 #  define TRACE_IRQS_ON
       
   200 #  define TRACE_IRQS_OFF
       
   201 #endif
       
   202 #ifdef CONFIG_DEBUG_LOCK_ALLOC
       
   203 #  define LOCKDEP_SYS_EXIT	ARCH_LOCKDEP_SYS_EXIT
       
   204 #  define LOCKDEP_SYS_EXIT_IRQ	ARCH_LOCKDEP_SYS_EXIT_IRQ
       
   205 # else
       
   206 #  define LOCKDEP_SYS_EXIT
       
   207 #  define LOCKDEP_SYS_EXIT_IRQ
       
   208 # endif
       
   209 
       
   210 #endif /* __ASSEMBLY__ */
       
   211 #endif