162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci#ifndef _X86_IRQFLAGS_H_
362306a36Sopenharmony_ci#define _X86_IRQFLAGS_H_
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci#include <asm/processor-flags.h>
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci#ifndef __ASSEMBLY__
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#include <asm/nospec-branch.h>
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci/*
1262306a36Sopenharmony_ci * Interrupt control:
1362306a36Sopenharmony_ci */
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci/* Declaration required for gcc < 4.9 to prevent -Werror=missing-prototypes */
1662306a36Sopenharmony_ciextern inline unsigned long native_save_fl(void);
1762306a36Sopenharmony_ciextern __always_inline unsigned long native_save_fl(void)
1862306a36Sopenharmony_ci{
1962306a36Sopenharmony_ci	unsigned long flags;
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci	/*
2262306a36Sopenharmony_ci	 * "=rm" is safe here, because "pop" adjusts the stack before
2362306a36Sopenharmony_ci	 * it evaluates its effective address -- this is part of the
2462306a36Sopenharmony_ci	 * documented behavior of the "pop" instruction.
2562306a36Sopenharmony_ci	 */
2662306a36Sopenharmony_ci	asm volatile("# __raw_save_flags\n\t"
2762306a36Sopenharmony_ci		     "pushf ; pop %0"
2862306a36Sopenharmony_ci		     : "=rm" (flags)
2962306a36Sopenharmony_ci		     : /* no input */
3062306a36Sopenharmony_ci		     : "memory");
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ci	return flags;
3362306a36Sopenharmony_ci}
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_cistatic __always_inline void native_irq_disable(void)
3662306a36Sopenharmony_ci{
3762306a36Sopenharmony_ci	asm volatile("cli": : :"memory");
3862306a36Sopenharmony_ci}
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_cistatic __always_inline void native_irq_enable(void)
4162306a36Sopenharmony_ci{
4262306a36Sopenharmony_ci	asm volatile("sti": : :"memory");
4362306a36Sopenharmony_ci}
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_cistatic __always_inline void native_safe_halt(void)
4662306a36Sopenharmony_ci{
4762306a36Sopenharmony_ci	mds_idle_clear_cpu_buffers();
4862306a36Sopenharmony_ci	asm volatile("sti; hlt": : :"memory");
4962306a36Sopenharmony_ci}
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_cistatic __always_inline void native_halt(void)
5262306a36Sopenharmony_ci{
5362306a36Sopenharmony_ci	mds_idle_clear_cpu_buffers();
5462306a36Sopenharmony_ci	asm volatile("hlt": : :"memory");
5562306a36Sopenharmony_ci}
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_ci#endif
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_ci#ifdef CONFIG_PARAVIRT_XXL
6062306a36Sopenharmony_ci#include <asm/paravirt.h>
6162306a36Sopenharmony_ci#else
6262306a36Sopenharmony_ci#ifndef __ASSEMBLY__
6362306a36Sopenharmony_ci#include <linux/types.h>
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_cistatic __always_inline unsigned long arch_local_save_flags(void)
6662306a36Sopenharmony_ci{
6762306a36Sopenharmony_ci	return native_save_fl();
6862306a36Sopenharmony_ci}
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_cistatic __always_inline void arch_local_irq_disable(void)
7162306a36Sopenharmony_ci{
7262306a36Sopenharmony_ci	native_irq_disable();
7362306a36Sopenharmony_ci}
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_cistatic __always_inline void arch_local_irq_enable(void)
7662306a36Sopenharmony_ci{
7762306a36Sopenharmony_ci	native_irq_enable();
7862306a36Sopenharmony_ci}
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_ci/*
8162306a36Sopenharmony_ci * Used in the idle loop; sti takes one instruction cycle
8262306a36Sopenharmony_ci * to complete:
8362306a36Sopenharmony_ci */
8462306a36Sopenharmony_cistatic __always_inline void arch_safe_halt(void)
8562306a36Sopenharmony_ci{
8662306a36Sopenharmony_ci	native_safe_halt();
8762306a36Sopenharmony_ci}
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_ci/*
9062306a36Sopenharmony_ci * Used when interrupts are already enabled or to
9162306a36Sopenharmony_ci * shutdown the processor:
9262306a36Sopenharmony_ci */
9362306a36Sopenharmony_cistatic __always_inline void halt(void)
9462306a36Sopenharmony_ci{
9562306a36Sopenharmony_ci	native_halt();
9662306a36Sopenharmony_ci}
9762306a36Sopenharmony_ci
9862306a36Sopenharmony_ci/*
9962306a36Sopenharmony_ci * For spinlocks, etc:
10062306a36Sopenharmony_ci */
10162306a36Sopenharmony_cistatic __always_inline unsigned long arch_local_irq_save(void)
10262306a36Sopenharmony_ci{
10362306a36Sopenharmony_ci	unsigned long flags = arch_local_save_flags();
10462306a36Sopenharmony_ci	arch_local_irq_disable();
10562306a36Sopenharmony_ci	return flags;
10662306a36Sopenharmony_ci}
10762306a36Sopenharmony_ci#else
10862306a36Sopenharmony_ci
10962306a36Sopenharmony_ci#ifdef CONFIG_X86_64
11062306a36Sopenharmony_ci#ifdef CONFIG_DEBUG_ENTRY
11162306a36Sopenharmony_ci#define SAVE_FLAGS		pushfq; popq %rax
11262306a36Sopenharmony_ci#endif
11362306a36Sopenharmony_ci
11462306a36Sopenharmony_ci#endif
11562306a36Sopenharmony_ci
11662306a36Sopenharmony_ci#endif /* __ASSEMBLY__ */
11762306a36Sopenharmony_ci#endif /* CONFIG_PARAVIRT_XXL */
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_ci#ifndef __ASSEMBLY__
12062306a36Sopenharmony_cistatic __always_inline int arch_irqs_disabled_flags(unsigned long flags)
12162306a36Sopenharmony_ci{
12262306a36Sopenharmony_ci	return !(flags & X86_EFLAGS_IF);
12362306a36Sopenharmony_ci}
12462306a36Sopenharmony_ci
12562306a36Sopenharmony_cistatic __always_inline int arch_irqs_disabled(void)
12662306a36Sopenharmony_ci{
12762306a36Sopenharmony_ci	unsigned long flags = arch_local_save_flags();
12862306a36Sopenharmony_ci
12962306a36Sopenharmony_ci	return arch_irqs_disabled_flags(flags);
13062306a36Sopenharmony_ci}
13162306a36Sopenharmony_ci
13262306a36Sopenharmony_cistatic __always_inline void arch_local_irq_restore(unsigned long flags)
13362306a36Sopenharmony_ci{
13462306a36Sopenharmony_ci	if (!arch_irqs_disabled_flags(flags))
13562306a36Sopenharmony_ci		arch_local_irq_enable();
13662306a36Sopenharmony_ci}
13762306a36Sopenharmony_ci#endif /* !__ASSEMBLY__ */
13862306a36Sopenharmony_ci
13962306a36Sopenharmony_ci#endif
140