/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_HARDIRQ_H #define _ASM_X86_HARDIRQ_H #include enum irq_stat_counts { IRQ_COUNT_NMI, #ifdef CONFIG_X86_LOCAL_APIC IRQ_COUNT_APIC_TIMER, IRQ_COUNT_SPURIOUS, IRQ_COUNT_APIC_PERF, IRQ_COUNT_IRQ_WORK, IRQ_COUNT_ICR_READ_RETRY, IRQ_COUNT_X86_PLATFORM_IPI, #endif #ifdef CONFIG_SMP IRQ_COUNT_RESCHEDULE, IRQ_COUNT_CALL_FUNCTION, #endif IRQ_COUNT_TLB, #ifdef CONFIG_X86_THERMAL_VECTOR IRQ_COUNT_THERMAL_APIC, #endif #ifdef CONFIG_X86_MCE_THRESHOLD IRQ_COUNT_THRESHOLD_APIC, #endif #ifdef CONFIG_X86_MCE_AMD IRQ_COUNT_DEFERRED_ERROR, #endif #ifdef CONFIG_X86_MCE IRQ_COUNT_MCE_EXCEPTION, IRQ_COUNT_MCE_POLL, #endif #ifdef CONFIG_X86_HV_CALLBACK_VECTOR IRQ_COUNT_HYPERVISOR_CALLBACK, #endif #if IS_ENABLED(CONFIG_HYPERV) IRQ_COUNT_HYPERV_REENLIGHTENMENT, IRQ_COUNT_HYPERV_STIMER0, #endif #if IS_ENABLED(CONFIG_KVM) IRQ_COUNT_POSTED_INTR, IRQ_COUNT_POSTED_INTR_NESTED, IRQ_COUNT_POSTED_INTR_WAKEUP, #endif #ifdef CONFIG_GUEST_PERF_EVENTS IRQ_COUNT_PERF_GUEST_MEDIATED_PMI, #endif #ifdef CONFIG_X86_POSTED_MSI IRQ_COUNT_POSTED_MSI_NOTIFICATION, #endif IRQ_COUNT_PIC_APIC_ERROR, #ifdef CONFIG_X86_IO_APIC IRQ_COUNT_IOAPIC_MISROUTED, #endif IRQ_COUNT_MAX, }; typedef struct { #if IS_ENABLED(CONFIG_CPU_MITIGATIONS) && IS_ENABLED(CONFIG_KVM_INTEL) u8 kvm_cpu_l1tf_flush_l1d; #endif unsigned int counts[IRQ_COUNT_MAX]; } ____cacheline_aligned irq_cpustat_t; DECLARE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat); #ifdef CONFIG_X86_POSTED_MSI DECLARE_PER_CPU_ALIGNED(struct pi_desc, posted_msi_pi_desc); #endif #define __ARCH_IRQ_STAT #define inc_irq_stat(index) this_cpu_inc(irq_stat.counts[IRQ_COUNT_##index]) void irq_stat_inc_and_enable(enum irq_stat_counts which); #ifdef CONFIG_X86_LOCAL_APIC #define inc_perf_irq_stat() inc_irq_stat(APIC_PERF) #else #define inc_perf_irq_stat() do { } while (0) #endif extern void ack_bad_irq(unsigned int irq); #ifdef CONFIG_PROC_FS extern u64 arch_irq_stat_cpu(unsigned int cpu); #define arch_irq_stat_cpu arch_irq_stat_cpu #endif DECLARE_PER_CPU_CACHE_HOT(u16, __softirq_pending); #define local_softirq_pending_ref __softirq_pending #if IS_ENABLED(CONFIG_CPU_MITIGATIONS) && IS_ENABLED(CONFIG_KVM_INTEL) /* * This function is called from noinstr interrupt contexts * and must be inlined to not get instrumentation. */ static __always_inline void kvm_set_cpu_l1tf_flush_l1d(void) { __this_cpu_write(irq_stat.kvm_cpu_l1tf_flush_l1d, 1); } static __always_inline void kvm_clear_cpu_l1tf_flush_l1d(void) { __this_cpu_write(irq_stat.kvm_cpu_l1tf_flush_l1d, 0); } static __always_inline bool kvm_get_cpu_l1tf_flush_l1d(void) { return __this_cpu_read(irq_stat.kvm_cpu_l1tf_flush_l1d); } #else /* !IS_ENABLED(CONFIG_KVM_INTEL) */ static __always_inline void kvm_set_cpu_l1tf_flush_l1d(void) { } #endif /* IS_ENABLED(CONFIG_KVM_INTEL) */ #endif /* _ASM_X86_HARDIRQ_H */