1 // SPDX-License-Identifier: GPL-2.0-only
3 * irq.c: API for in kernel interrupt controller
4 * Copyright (c) 2007, Intel Corporation.
5 * Copyright 2009 Red Hat, Inc. and/or its affiliates.
8 * Yaozu (Eddie) Dong <Eddie.dong@intel.com>
10 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
12 #include <linux/export.h>
13 #include <linux/kvm_host.h>
21 * check if there are pending timer events
24 int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu)
28 if (lapic_in_kernel(vcpu))
29 r = apic_has_pending_timer(vcpu);
30 if (kvm_xen_timer_enabled(vcpu))
31 r += kvm_xen_has_pending_timer(vcpu);
37 * check if there is a pending userspace external interrupt
39 static int pending_userspace_extint(struct kvm_vcpu *v)
41 return v->arch.pending_external_vector != -1;
45 * check if there is pending interrupt from
46 * non-APIC source without intack.
48 int kvm_cpu_has_extint(struct kvm_vcpu *v)
51 * FIXME: interrupt.injected represents an interrupt whose
52 * side-effects have already been applied (e.g. bit from IRR
53 * already moved to ISR). Therefore, it is incorrect to rely
54 * on interrupt.injected to know if there is a pending
55 * interrupt in the user-mode LAPIC.
56 * This leads to nVMX/nSVM not be able to distinguish
57 * if it should exit from L2 to L1 on EXTERNAL_INTERRUPT on
58 * pending interrupt or should re-inject an injected
61 if (!lapic_in_kernel(v))
62 return v->arch.interrupt.injected;
64 if (kvm_xen_has_interrupt(v))
67 if (!kvm_apic_accept_pic_intr(v))
70 if (irqchip_split(v->kvm))
71 return pending_userspace_extint(v);
73 return v->kvm->arch.vpic->output;
77 * check if there is injectable interrupt:
78 * when virtual interrupt delivery enabled,
79 * interrupt from apic will handled by hardware,
80 * we don't need to check it here.
82 int kvm_cpu_has_injectable_intr(struct kvm_vcpu *v)
84 if (kvm_cpu_has_extint(v))
87 if (!is_guest_mode(v) && kvm_vcpu_apicv_active(v))
90 return kvm_apic_has_interrupt(v) != -1; /* LAPIC */
92 EXPORT_SYMBOL_GPL(kvm_cpu_has_injectable_intr);
95 * check if there is pending interrupt without
98 int kvm_cpu_has_interrupt(struct kvm_vcpu *v)
100 if (kvm_cpu_has_extint(v))
103 return kvm_apic_has_interrupt(v) != -1; /* LAPIC */
105 EXPORT_SYMBOL_GPL(kvm_cpu_has_interrupt);
108 * Read pending interrupt(from non-APIC source)
111 static int kvm_cpu_get_extint(struct kvm_vcpu *v)
113 if (!kvm_cpu_has_extint(v)) {
114 WARN_ON(!lapic_in_kernel(v));
118 if (!lapic_in_kernel(v))
119 return v->arch.interrupt.nr;
121 if (kvm_xen_has_interrupt(v))
122 return v->kvm->arch.xen.upcall_vector;
124 if (irqchip_split(v->kvm)) {
125 int vector = v->arch.pending_external_vector;
127 v->arch.pending_external_vector = -1;
130 return kvm_pic_read_irq(v->kvm); /* PIC */
134 * Read pending interrupt vector and intack.
136 int kvm_cpu_get_interrupt(struct kvm_vcpu *v)
138 int vector = kvm_cpu_get_extint(v);
140 return vector; /* PIC */
142 return kvm_get_apic_interrupt(v); /* APIC */
144 EXPORT_SYMBOL_GPL(kvm_cpu_get_interrupt);
146 void kvm_inject_pending_timer_irqs(struct kvm_vcpu *vcpu)
148 if (lapic_in_kernel(vcpu))
149 kvm_inject_apic_timer_irqs(vcpu);
150 if (kvm_xen_timer_enabled(vcpu))
151 kvm_xen_inject_timer_irqs(vcpu);
154 void __kvm_migrate_timers(struct kvm_vcpu *vcpu)
156 __kvm_migrate_apic_timer(vcpu);
157 __kvm_migrate_pit_timer(vcpu);
158 static_call_cond(kvm_x86_migrate_timers)(vcpu);
161 bool kvm_arch_irqfd_allowed(struct kvm *kvm, struct kvm_irqfd *args)
163 bool resample = args->flags & KVM_IRQFD_FLAG_RESAMPLE;
165 return resample ? irqchip_kernel(kvm) : irqchip_in_kernel(kvm);
168 bool kvm_arch_irqchip_in_kernel(struct kvm *kvm)
170 return irqchip_in_kernel(kvm);