irqflags_64.h 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  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. /*
  13. * Interrupt control:
  14. */
  15. static inline unsigned long __raw_local_save_flags(void)
  16. {
  17. unsigned long flags;
  18. __asm__ __volatile__(
  19. "# __raw_save_flags\n\t"
  20. "pushfq ; popq %q0"
  21. : "=g" (flags)
  22. : /* no input */
  23. : "memory"
  24. );
  25. return flags;
  26. }
  27. #define raw_local_save_flags(flags) \
  28. do { (flags) = __raw_local_save_flags(); } while (0)
  29. static inline void raw_local_irq_restore(unsigned long flags)
  30. {
  31. __asm__ __volatile__(
  32. "pushq %0 ; popfq"
  33. : /* no output */
  34. :"g" (flags)
  35. :"memory", "cc"
  36. );
  37. }
  38. #ifdef CONFIG_X86_VSMP
  39. /*
  40. * Interrupt control for the VSMP architecture:
  41. */
  42. static inline void raw_local_irq_disable(void)
  43. {
  44. unsigned long flags = __raw_local_save_flags();
  45. raw_local_irq_restore((flags & ~X86_EFLAGS_IF) | X86_EFLAGS_AC);
  46. }
  47. static inline void raw_local_irq_enable(void)
  48. {
  49. unsigned long flags = __raw_local_save_flags();
  50. raw_local_irq_restore((flags | X86_EFLAGS_IF) & (~X86_EFLAGS_AC));
  51. }
  52. static inline int raw_irqs_disabled_flags(unsigned long flags)
  53. {
  54. return !(flags & X86_EFLAGS_IF) || (flags & X86_EFLAGS_AC);
  55. }
  56. #else /* CONFIG_X86_VSMP */
  57. static inline void raw_local_irq_disable(void)
  58. {
  59. __asm__ __volatile__("cli" : : : "memory");
  60. }
  61. static inline void raw_local_irq_enable(void)
  62. {
  63. __asm__ __volatile__("sti" : : : "memory");
  64. }
  65. static inline int raw_irqs_disabled_flags(unsigned long flags)
  66. {
  67. return !(flags & X86_EFLAGS_IF);
  68. }
  69. #endif
  70. /*
  71. * For spinlocks, etc.:
  72. */
  73. static inline unsigned long __raw_local_irq_save(void)
  74. {
  75. unsigned long flags = __raw_local_save_flags();
  76. raw_local_irq_disable();
  77. return flags;
  78. }
  79. #define raw_local_irq_save(flags) \
  80. do { (flags) = __raw_local_irq_save(); } while (0)
  81. static inline int raw_irqs_disabled(void)
  82. {
  83. unsigned long flags = __raw_local_save_flags();
  84. return raw_irqs_disabled_flags(flags);
  85. }
  86. /*
  87. * makes the traced hardirq state match with the machine state
  88. *
  89. * should be a rarely used function, only in places where its
  90. * otherwise impossible to know the irq state, like in traps.
  91. */
  92. static inline void trace_hardirqs_fixup_flags(unsigned long flags)
  93. {
  94. if (raw_irqs_disabled_flags(flags))
  95. trace_hardirqs_off();
  96. else
  97. trace_hardirqs_on();
  98. }
  99. static inline void trace_hardirqs_fixup(void)
  100. {
  101. unsigned long flags = __raw_local_save_flags();
  102. trace_hardirqs_fixup_flags(flags);
  103. }
  104. /*
  105. * Used in the idle loop; sti takes one instruction cycle
  106. * to complete:
  107. */
  108. static inline void raw_safe_halt(void)
  109. {
  110. __asm__ __volatile__("sti; hlt" : : : "memory");
  111. }
  112. /*
  113. * Used when interrupts are already enabled or to
  114. * shutdown the processor:
  115. */
  116. static inline void halt(void)
  117. {
  118. __asm__ __volatile__("hlt": : :"memory");
  119. }
  120. #else /* __ASSEMBLY__: */
  121. # ifdef CONFIG_TRACE_IRQFLAGS
  122. # define TRACE_IRQS_ON call trace_hardirqs_on_thunk
  123. # define TRACE_IRQS_OFF call trace_hardirqs_off_thunk
  124. # else
  125. # define TRACE_IRQS_ON
  126. # define TRACE_IRQS_OFF
  127. # endif
  128. # ifdef CONFIG_DEBUG_LOCK_ALLOC
  129. # define LOCKDEP_SYS_EXIT call lockdep_sys_exit_thunk
  130. # define LOCKDEP_SYS_EXIT_IRQ \
  131. TRACE_IRQS_ON; \
  132. sti; \
  133. SAVE_REST; \
  134. LOCKDEP_SYS_EXIT; \
  135. RESTORE_REST; \
  136. cli; \
  137. TRACE_IRQS_OFF;
  138. # else
  139. # define LOCKDEP_SYS_EXIT
  140. # define LOCKDEP_SYS_EXIT_IRQ
  141. # endif
  142. #endif
  143. #endif