1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #ifndef _ASM_X86_HARDIRQ_H 3 #define _ASM_X86_HARDIRQ_H 4 5 #include <linux/threads.h> 6 7 enum irq_stat_counts { 8 IRQ_COUNT_NMI, 9 #ifdef CONFIG_X86_LOCAL_APIC 10 IRQ_COUNT_APIC_TIMER, 11 IRQ_COUNT_SPURIOUS, 12 IRQ_COUNT_APIC_PERF, 13 IRQ_COUNT_IRQ_WORK, 14 IRQ_COUNT_ICR_READ_RETRY, 15 IRQ_COUNT_X86_PLATFORM_IPI, 16 #endif 17 #ifdef CONFIG_SMP 18 IRQ_COUNT_RESCHEDULE, 19 IRQ_COUNT_CALL_FUNCTION, 20 #endif 21 IRQ_COUNT_TLB, 22 #ifdef CONFIG_X86_THERMAL_VECTOR 23 IRQ_COUNT_THERMAL_APIC, 24 #endif 25 #ifdef CONFIG_X86_MCE_THRESHOLD 26 IRQ_COUNT_THRESHOLD_APIC, 27 #endif 28 #ifdef CONFIG_X86_MCE_AMD 29 IRQ_COUNT_DEFERRED_ERROR, 30 #endif 31 #ifdef CONFIG_X86_MCE 32 IRQ_COUNT_MCE_EXCEPTION, 33 IRQ_COUNT_MCE_POLL, 34 #endif 35 #ifdef CONFIG_X86_HV_CALLBACK_VECTOR 36 IRQ_COUNT_HYPERVISOR_CALLBACK, 37 #endif 38 #if IS_ENABLED(CONFIG_HYPERV) 39 IRQ_COUNT_HYPERV_REENLIGHTENMENT, 40 IRQ_COUNT_HYPERV_STIMER0, 41 #endif 42 #if IS_ENABLED(CONFIG_KVM) 43 IRQ_COUNT_POSTED_INTR, 44 IRQ_COUNT_POSTED_INTR_NESTED, 45 IRQ_COUNT_POSTED_INTR_WAKEUP, 46 #endif 47 #ifdef CONFIG_GUEST_PERF_EVENTS 48 IRQ_COUNT_PERF_GUEST_MEDIATED_PMI, 49 #endif 50 #ifdef CONFIG_X86_POSTED_MSI 51 IRQ_COUNT_POSTED_MSI_NOTIFICATION, 52 #endif 53 IRQ_COUNT_PIC_APIC_ERROR, 54 #ifdef CONFIG_X86_IO_APIC 55 IRQ_COUNT_IOAPIC_MISROUTED, 56 #endif 57 IRQ_COUNT_MAX, 58 }; 59 60 typedef struct { 61 #if IS_ENABLED(CONFIG_CPU_MITIGATIONS) && IS_ENABLED(CONFIG_KVM_INTEL) 62 u8 kvm_cpu_l1tf_flush_l1d; 63 #endif 64 unsigned int counts[IRQ_COUNT_MAX]; 65 } ____cacheline_aligned irq_cpustat_t; 66 67 DECLARE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat); 68 69 #ifdef CONFIG_X86_POSTED_MSI 70 DECLARE_PER_CPU_ALIGNED(struct pi_desc, posted_msi_pi_desc); 71 #endif 72 #define __ARCH_IRQ_STAT 73 74 #define inc_irq_stat(index) this_cpu_inc(irq_stat.counts[IRQ_COUNT_##index]) 75 void irq_stat_inc_and_enable(enum irq_stat_counts which); 76 77 #ifdef CONFIG_X86_LOCAL_APIC 78 #define inc_perf_irq_stat() inc_irq_stat(APIC_PERF) 79 #else 80 #define inc_perf_irq_stat() do { } while (0) 81 #endif 82 83 extern void ack_bad_irq(unsigned int irq); 84 85 #ifdef CONFIG_PROC_FS 86 extern u64 arch_irq_stat_cpu(unsigned int cpu); 87 #define arch_irq_stat_cpu arch_irq_stat_cpu 88 #endif 89 90 DECLARE_PER_CPU_CACHE_HOT(u16, __softirq_pending); 91 #define local_softirq_pending_ref __softirq_pending 92 93 #if IS_ENABLED(CONFIG_CPU_MITIGATIONS) && IS_ENABLED(CONFIG_KVM_INTEL) 94 /* 95 * This function is called from noinstr interrupt contexts 96 * and must be inlined to not get instrumentation. 97 */ 98 static __always_inline void kvm_set_cpu_l1tf_flush_l1d(void) 99 { 100 __this_cpu_write(irq_stat.kvm_cpu_l1tf_flush_l1d, 1); 101 } 102 103 static __always_inline void kvm_clear_cpu_l1tf_flush_l1d(void) 104 { 105 __this_cpu_write(irq_stat.kvm_cpu_l1tf_flush_l1d, 0); 106 } 107 108 static __always_inline bool kvm_get_cpu_l1tf_flush_l1d(void) 109 { 110 return __this_cpu_read(irq_stat.kvm_cpu_l1tf_flush_l1d); 111 } 112 #else /* !IS_ENABLED(CONFIG_KVM_INTEL) */ 113 static __always_inline void kvm_set_cpu_l1tf_flush_l1d(void) { } 114 #endif /* IS_ENABLED(CONFIG_KVM_INTEL) */ 115 116 #endif /* _ASM_X86_HARDIRQ_H */ 117