Merge tag 'pci-v6.16-fixes-3' of git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci
[linux-2.6-block.git] / arch / x86 / include / asm / irqflags.h
CommitLineData
b2441318 1/* SPDX-License-Identifier: GPL-2.0 */
6abcd98f
GOC
2#ifndef _X86_IRQFLAGS_H_
3#define _X86_IRQFLAGS_H_
4
5#include <asm/processor-flags.h>
6
24a295e4 7#ifndef __ASSEMBLER__
6727ad9e 8
07f07f55
TG
9#include <asm/nospec-branch.h>
10
6abcd98f
GOC
11/*
12 * Interrupt control:
13 */
14
208cbb32
ND
15/* Declaration required for gcc < 4.9 to prevent -Werror=missing-prototypes */
16extern inline unsigned long native_save_fl(void);
7a745be1 17extern __always_inline unsigned long native_save_fl(void)
6abcd98f
GOC
18{
19 unsigned long flags;
20
f1f029c7 21 /*
ab94fcf5
PA
22 * "=rm" is safe here, because "pop" adjusts the stack before
23 * it evaluates its effective address -- this is part of the
24 * documented behavior of the "pop" instruction.
f1f029c7 25 */
cf7f7191
JP
26 asm volatile("# __raw_save_flags\n\t"
27 "pushf ; pop %0"
ab94fcf5 28 : "=rm" (flags)
cf7f7191
JP
29 : /* no input */
30 : "memory");
6abcd98f
GOC
31
32 return flags;
33}
34
7a745be1 35static __always_inline void native_irq_disable(void)
6abcd98f
GOC
36{
37 asm volatile("cli": : :"memory");
38}
39
7a745be1 40static __always_inline void native_irq_enable(void)
6abcd98f
GOC
41{
42 asm volatile("sti": : :"memory");
43}
44
2b5a0e42 45static __always_inline void native_safe_halt(void)
6abcd98f 46{
f9af88a3 47 x86_idle_clear_cpu_buffers();
6abcd98f
GOC
48 asm volatile("sti; hlt": : :"memory");
49}
50
2b5a0e42 51static __always_inline void native_halt(void)
6abcd98f 52{
f9af88a3 53 x86_idle_clear_cpu_buffers();
6abcd98f
GOC
54 asm volatile("hlt": : :"memory");
55}
56
b547fc2c
TL
57static __always_inline int native_irqs_disabled_flags(unsigned long flags)
58{
59 return !(flags & X86_EFLAGS_IF);
60}
61
62static __always_inline unsigned long native_local_irq_save(void)
63{
64 unsigned long flags = native_save_fl();
65
66 native_irq_disable();
67
68 return flags;
69}
70
71static __always_inline void native_local_irq_restore(unsigned long flags)
72{
73 if (!native_irqs_disabled_flags(flags))
74 native_irq_enable();
75}
76
6abcd98f
GOC
77#endif
78
22cc5ca5
KS
79#ifndef CONFIG_PARAVIRT
80#ifndef __ASSEMBLY__
81/*
82 * Used in the idle loop; sti takes one instruction cycle
83 * to complete:
84 */
85static __always_inline void arch_safe_halt(void)
86{
87 native_safe_halt();
88}
89
90/*
91 * Used when interrupts are already enabled or to
92 * shutdown the processor:
93 */
94static __always_inline void halt(void)
95{
96 native_halt();
97}
98#endif /* __ASSEMBLY__ */
99#endif /* CONFIG_PARAVIRT */
100
6da63eb2 101#ifdef CONFIG_PARAVIRT_XXL
6abcd98f
GOC
102#include <asm/paravirt.h>
103#else
24a295e4 104#ifndef __ASSEMBLER__
e08fbb78 105#include <linux/types.h>
6abcd98f 106
7a745be1 107static __always_inline unsigned long arch_local_save_flags(void)
6abcd98f
GOC
108{
109 return native_save_fl();
110}
111
7a745be1 112static __always_inline void arch_local_irq_disable(void)
6abcd98f
GOC
113{
114 native_irq_disable();
115}
116
7a745be1 117static __always_inline void arch_local_irq_enable(void)
6abcd98f
GOC
118{
119 native_irq_enable();
120}
121
6abcd98f
GOC
122/*
123 * For spinlocks, etc:
124 */
7a745be1 125static __always_inline unsigned long arch_local_irq_save(void)
6abcd98f 126{
df9ee292
DH
127 unsigned long flags = arch_local_save_flags();
128 arch_local_irq_disable();
6abcd98f
GOC
129 return flags;
130}
131#else
132
9bad5658
JG
133#ifdef CONFIG_X86_64
134#ifdef CONFIG_DEBUG_ENTRY
fafe5e74 135#define SAVE_FLAGS pushfq; popq %rax
9bad5658 136#endif
9bad5658 137
6abcd98f
GOC
138#endif
139
24a295e4 140#endif /* __ASSEMBLER__ */
9bad5658 141#endif /* CONFIG_PARAVIRT_XXL */
6abcd98f 142
24a295e4 143#ifndef __ASSEMBLER__
7a745be1 144static __always_inline int arch_irqs_disabled_flags(unsigned long flags)
6abcd98f
GOC
145{
146 return !(flags & X86_EFLAGS_IF);
147}
148
7a745be1 149static __always_inline int arch_irqs_disabled(void)
6abcd98f 150{
df9ee292 151 unsigned long flags = arch_local_save_flags();
6abcd98f 152
df9ee292 153 return arch_irqs_disabled_flags(flags);
6abcd98f 154}
ab234a26
JG
155
156static __always_inline void arch_local_irq_restore(unsigned long flags)
157{
158 if (!arch_irqs_disabled_flags(flags))
159 arch_local_irq_enable();
160}
24a295e4 161#endif /* !__ASSEMBLER__ */
6abcd98f 162
96a388de 163#endif