/* * SPDX-License-Identifier: GPL-2.0 * * Copyright (C) 2019 Philippe Gerum . */ #ifndef _ASM_X86_IRQ_PIPELINE_H #define _ASM_X86_IRQ_PIPELINE_H #include #ifdef CONFIG_IRQ_PIPELINE #include #define FIRST_SYSTEM_IRQ NR_IRQS #define TIMER_OOB_IPI apicm_vector_irq(TIMER_OOB_VECTOR) #define RESCHEDULE_OOB_IPI apicm_vector_irq(RESCHEDULE_OOB_VECTOR) #define apicm_irq_vector(__irq) ((__irq) - FIRST_SYSTEM_IRQ + FIRST_SYSTEM_VECTOR) #define apicm_vector_irq(__vec) ((__vec) - FIRST_SYSTEM_VECTOR + FIRST_SYSTEM_IRQ) #define X86_EFLAGS_SS_BIT 31 static inline notrace unsigned long arch_irqs_virtual_to_native_flags(int stalled) { return (!stalled) << X86_EFLAGS_IF_BIT; } static inline notrace unsigned long arch_irqs_native_to_virtual_flags(unsigned long flags) { return hard_irqs_disabled_flags(flags) << X86_EFLAGS_SS_BIT; } #ifndef CONFIG_PARAVIRT_XXL static inline notrace unsigned long arch_local_irq_save(void) { int stalled = inband_irq_save(); barrier(); return arch_irqs_virtual_to_native_flags(stalled); } static inline notrace void arch_local_irq_enable(void) { barrier(); inband_irq_enable(); } static inline notrace void arch_local_irq_disable(void) { inband_irq_disable(); barrier(); } static inline notrace unsigned long arch_local_save_flags(void) { int stalled = inband_irqs_disabled(); barrier(); return arch_irqs_virtual_to_native_flags(stalled); } static inline notrace void arch_local_irq_restore(unsigned long flags) { inband_irq_restore(native_irqs_disabled_flags(flags)); barrier(); } #endif /* !CONFIG_PARAVIRT_XXL */ static inline void arch_save_timer_regs(struct pt_regs *dst, struct pt_regs *src) { dst->flags = src->flags; dst->cs = src->cs; dst->ip = src->ip; dst->bp = src->bp; dst->ss = src->ss; dst->sp = src->sp; } static inline bool arch_steal_pipelined_tick(struct pt_regs *regs) { return !(regs->flags & X86_EFLAGS_IF); } static inline int arch_enable_oob_stage(void) { return 0; } static inline void handle_arch_irq(struct pt_regs *regs) { } #else /* !CONFIG_IRQ_PIPELINE */ struct pt_regs; #ifndef CONFIG_PARAVIRT_XXL static inline notrace unsigned long arch_local_save_flags(void) { return native_save_fl(); } static inline notrace void arch_local_irq_restore(unsigned long flags) { native_restore_fl(flags); } static inline notrace void arch_local_irq_disable(void) { native_irq_disable(); } static inline notrace void arch_local_irq_enable(void) { native_irq_enable(); } /* * For spinlocks, etc: */ static inline notrace unsigned long arch_local_irq_save(void) { unsigned long flags = arch_local_save_flags(); arch_local_irq_disable(); return flags; } #endif /* !CONFIG_PARAVIRT_XXL */ #endif /* !CONFIG_IRQ_PIPELINE */ #endif /* _ASM_X86_IRQ_PIPELINE_H */