Line data Source code
1 : /* SPDX-License-Identifier: GPL-2.0 */ 2 : #ifndef _X86_IRQFLAGS_H_ 3 : #define _X86_IRQFLAGS_H_ 4 : 5 : #include <asm/processor-flags.h> 6 : 7 : #ifndef __ASSEMBLY__ 8 : 9 : #include <asm/nospec-branch.h> 10 : 11 : /* 12 : * Interrupt control: 13 : */ 14 : 15 : /* Declaration required for gcc < 4.9 to prevent -Werror=missing-prototypes */ 16 : extern inline unsigned long native_save_fl(void); 17 : extern __always_inline unsigned long native_save_fl(void) 18 : { 19 2996048326 : unsigned long flags; 20 : 21 : /* 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. 25 : */ 26 2996048326 : asm volatile("# __raw_save_flags\n\t" 27 : "pushf ; pop %0" 28 : : "=rm" (flags) 29 : : /* no input */ 30 : : "memory"); 31 : 32 2996023218 : return flags; 33 : } 34 : 35 : static __always_inline void native_irq_disable(void) 36 : { 37 3028752539 : asm volatile("cli": : :"memory"); 38 : } 39 : 40 : static __always_inline void native_irq_enable(void) 41 : { 42 2973564589 : asm volatile("sti": : :"memory"); 43 : } 44 : 45 : static __always_inline void native_safe_halt(void) 46 : { 47 : mds_idle_clear_cpu_buffers(); 48 : asm volatile("sti; hlt": : :"memory"); 49 : } 50 : 51 : static __always_inline void native_halt(void) 52 : { 53 : mds_idle_clear_cpu_buffers(); 54 : asm volatile("hlt": : :"memory"); 55 : } 56 : 57 : #endif 58 : 59 : #ifdef CONFIG_PARAVIRT_XXL 60 : #include <asm/paravirt.h> 61 : #else 62 : #ifndef __ASSEMBLY__ 63 : #include <linux/types.h> 64 : 65 : static __always_inline unsigned long arch_local_save_flags(void) 66 : { 67 2996048326 : return native_save_fl(); 68 : } 69 : 70 : static __always_inline void arch_local_irq_disable(void) 71 : { 72 3028752539 : native_irq_disable(); 73 : } 74 : 75 : static __always_inline void arch_local_irq_enable(void) 76 : { 77 2973564589 : native_irq_enable(); 78 2795168594 : } 79 : 80 : /* 81 : * Used in the idle loop; sti takes one instruction cycle 82 : * to complete: 83 : */ 84 : static __always_inline void arch_safe_halt(void) 85 : { 86 : native_safe_halt(); 87 : } 88 : 89 : /* 90 : * Used when interrupts are already enabled or to 91 : * shutdown the processor: 92 : */ 93 : static __always_inline void halt(void) 94 : { 95 : native_halt(); 96 : } 97 : 98 : /* 99 : * For spinlocks, etc: 100 : */ 101 : static __always_inline unsigned long arch_local_irq_save(void) 102 : { 103 2850633582 : unsigned long flags = arch_local_save_flags(); 104 2850597905 : arch_local_irq_disable(); 105 2850541904 : return flags; 106 : } 107 : #else 108 : 109 : #ifdef CONFIG_X86_64 110 : #ifdef CONFIG_DEBUG_ENTRY 111 : #define SAVE_FLAGS pushfq; popq %rax 112 : #endif 113 : 114 : #endif 115 : 116 : #endif /* __ASSEMBLY__ */ 117 : #endif /* CONFIG_PARAVIRT_XXL */ 118 : 119 : #ifndef __ASSEMBLY__ 120 : static __always_inline int arch_irqs_disabled_flags(unsigned long flags) 121 : { 122 2996256398 : return !(flags & X86_EFLAGS_IF); 123 : } 124 : 125 : static __always_inline int arch_irqs_disabled(void) 126 : { 127 : unsigned long flags = arch_local_save_flags(); 128 : 129 : return arch_irqs_disabled_flags(flags); 130 : } 131 : 132 : static __always_inline void arch_local_irq_restore(unsigned long flags) 133 : { 134 2850831085 : if (!arch_irqs_disabled_flags(flags)) 135 2795199471 : arch_local_irq_enable(); 136 : } 137 : #endif /* !__ASSEMBLY__ */ 138 : 139 : #endif