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.
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 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 #ifdef CONFIG_KVM_XEN
122 if (kvm_xen_has_interrupt(v))
123 return v->kvm->arch.xen.upcall_vector;
126 if (irqchip_split(v->kvm)) {
127 int vector = v->arch.pending_external_vector;
129 v->arch.pending_external_vector = -1;
132 return kvm_pic_read_irq(v->kvm); /* PIC */
134 EXPORT_SYMBOL_GPL(kvm_cpu_get_extint);
137 * Read pending interrupt vector and intack.
139 int kvm_cpu_get_interrupt(struct kvm_vcpu *v)
141 int vector = kvm_cpu_get_extint(v);
143 return vector; /* PIC */
145 vector = kvm_apic_has_interrupt(v); /* APIC */
147 kvm_apic_ack_interrupt(v, vector);
152 void kvm_inject_pending_timer_irqs(struct kvm_vcpu *vcpu)
154 if (lapic_in_kernel(vcpu))
155 kvm_inject_apic_timer_irqs(vcpu);
156 if (kvm_xen_timer_enabled(vcpu))
157 kvm_xen_inject_timer_irqs(vcpu);
160 void __kvm_migrate_timers(struct kvm_vcpu *vcpu)
162 __kvm_migrate_apic_timer(vcpu);
163 __kvm_migrate_pit_timer(vcpu);
164 kvm_x86_call(migrate_timers)(vcpu);
167 bool kvm_arch_irqfd_allowed(struct kvm *kvm, struct kvm_irqfd *args)
169 bool resample = args->flags & KVM_IRQFD_FLAG_RESAMPLE;
171 return resample ? irqchip_kernel(kvm) : irqchip_in_kernel(kvm);
174 bool kvm_arch_irqchip_in_kernel(struct kvm *kvm)
176 return irqchip_in_kernel(kvm);