irqflags_32.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  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. #ifndef __ASSEMBLY__
  12. static inline unsigned long native_save_fl(void)
  13. {
  14. unsigned long f;
  15. asm volatile("pushfl ; popl %0":"=g" (f): /* no input */);
  16. return f;
  17. }
  18. static inline void native_restore_fl(unsigned long f)
  19. {
  20. asm volatile("pushl %0 ; popfl": /* no output */
  21. :"g" (f)
  22. :"memory", "cc");
  23. }
  24. static inline void native_irq_disable(void)
  25. {
  26. asm volatile("cli": : :"memory");
  27. }
  28. static inline void native_irq_enable(void)
  29. {
  30. asm volatile("sti": : :"memory");
  31. }
  32. static inline void native_safe_halt(void)
  33. {
  34. asm volatile("sti; hlt": : :"memory");
  35. }
  36. static inline void native_halt(void)
  37. {
  38. asm volatile("hlt": : :"memory");
  39. }
  40. #endif /* __ASSEMBLY__ */
  41. #ifdef CONFIG_PARAVIRT
  42. #include <asm/paravirt.h>
  43. #else
  44. #ifndef __ASSEMBLY__
  45. static inline unsigned long __raw_local_save_flags(void)
  46. {
  47. return native_save_fl();
  48. }
  49. static inline void raw_local_irq_restore(unsigned long flags)
  50. {
  51. native_restore_fl(flags);
  52. }
  53. static inline void raw_local_irq_disable(void)
  54. {
  55. native_irq_disable();
  56. }
  57. static inline void raw_local_irq_enable(void)
  58. {
  59. native_irq_enable();
  60. }
  61. /*
  62. * Used in the idle loop; sti takes one instruction cycle
  63. * to complete:
  64. */
  65. static inline void raw_safe_halt(void)
  66. {
  67. native_safe_halt();
  68. }
  69. /*
  70. * Used when interrupts are already enabled or to
  71. * shutdown the processor:
  72. */
  73. static inline void halt(void)
  74. {
  75. native_halt();
  76. }
  77. /*
  78. * For spinlocks, etc:
  79. */
  80. static inline unsigned long __raw_local_irq_save(void)
  81. {
  82. unsigned long flags = __raw_local_save_flags();
  83. raw_local_irq_disable();
  84. return flags;
  85. }
  86. #else
  87. #define DISABLE_INTERRUPTS(clobbers) cli
  88. #define ENABLE_INTERRUPTS(clobbers) sti
  89. #define ENABLE_INTERRUPTS_SYSEXIT sti; sysexit
  90. #define INTERRUPT_RETURN iret
  91. #define GET_CR0_INTO_EAX movl %cr0, %eax
  92. #endif /* __ASSEMBLY__ */
  93. #endif /* CONFIG_PARAVIRT */
  94. #ifndef __ASSEMBLY__
  95. #define raw_local_save_flags(flags) \
  96. do { (flags) = __raw_local_save_flags(); } while (0)
  97. #define raw_local_irq_save(flags) \
  98. do { (flags) = __raw_local_irq_save(); } while (0)
  99. static inline int raw_irqs_disabled_flags(unsigned long flags)
  100. {
  101. return !(flags & X86_EFLAGS_IF);
  102. }
  103. static inline int raw_irqs_disabled(void)
  104. {
  105. unsigned long flags = __raw_local_save_flags();
  106. return raw_irqs_disabled_flags(flags);
  107. }
  108. /*
  109. * makes the traced hardirq state match with the machine state
  110. *
  111. * should be a rarely used function, only in places where its
  112. * otherwise impossible to know the irq state, like in traps.
  113. */
  114. static inline void trace_hardirqs_fixup_flags(unsigned long flags)
  115. {
  116. if (raw_irqs_disabled_flags(flags))
  117. trace_hardirqs_off();
  118. else
  119. trace_hardirqs_on();
  120. }
  121. static inline void trace_hardirqs_fixup(void)
  122. {
  123. unsigned long flags = __raw_local_save_flags();
  124. trace_hardirqs_fixup_flags(flags);
  125. }
  126. #endif /* __ASSEMBLY__ */
  127. /*
  128. * Do the CPU's IRQ-state tracing from assembly code. We call a
  129. * C function, so save all the C-clobbered registers:
  130. */
  131. #ifdef CONFIG_TRACE_IRQFLAGS
  132. # define TRACE_IRQS_ON \
  133. pushl %eax; \
  134. pushl %ecx; \
  135. pushl %edx; \
  136. call trace_hardirqs_on; \
  137. popl %edx; \
  138. popl %ecx; \
  139. popl %eax;
  140. # define TRACE_IRQS_OFF \
  141. pushl %eax; \
  142. pushl %ecx; \
  143. pushl %edx; \
  144. call trace_hardirqs_off; \
  145. popl %edx; \
  146. popl %ecx; \
  147. popl %eax;
  148. #else
  149. # define TRACE_IRQS_ON
  150. # define TRACE_IRQS_OFF
  151. #endif
  152. #ifdef CONFIG_DEBUG_LOCK_ALLOC
  153. # define LOCKDEP_SYS_EXIT \
  154. pushl %eax; \
  155. pushl %ecx; \
  156. pushl %edx; \
  157. call lockdep_sys_exit; \
  158. popl %edx; \
  159. popl %ecx; \
  160. popl %eax;
  161. #else
  162. # define LOCKDEP_SYS_EXIT
  163. #endif
  164. #endif