1 /* 2 * irq.c: API for in kernel interrupt controller 3 * Copyright (c) 2007, Intel Corporation. 4 * Copyright 2009 Red Hat, Inc. and/or its affiliates. 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms and conditions of the GNU General Public License, 8 * version 2, as published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 13 * more details. 14 * 15 * You should have received a copy of the GNU General Public License along with 16 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple 17 * Place - Suite 330, Boston, MA 02111-1307 USA. 18 * Authors: 19 * Yaozu (Eddie) Dong <Eddie.dong@intel.com> 20 * 21 */ 22 23 #include <linux/module.h> 24 #include <linux/kvm_host.h> 25 26 #include "irq.h" 27 #include "i8254.h" 28 #include "x86.h" 29 30 /* 31 * check if there are pending timer events 32 * to be processed. 33 */ 34 int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu) 35 { 36 return apic_has_pending_timer(vcpu); 37 } 38 EXPORT_SYMBOL(kvm_cpu_has_pending_timer); 39 40 /* 41 * check if there is pending interrupt without 42 * intack. 43 */ 44 int kvm_cpu_has_interrupt(struct kvm_vcpu *v) 45 { 46 struct kvm_pic *s; 47 48 if (!irqchip_in_kernel(v->kvm)) 49 return v->arch.interrupt.pending; 50 51 if (kvm_apic_has_interrupt(v) == -1) { /* LAPIC */ 52 if (kvm_apic_accept_pic_intr(v)) { 53 s = pic_irqchip(v->kvm); /* PIC */ 54 return s->output; 55 } else 56 return 0; 57 } 58 return 1; 59 } 60 EXPORT_SYMBOL_GPL(kvm_cpu_has_interrupt); 61 62 /* 63 * Read pending interrupt vector and intack. 64 */ 65 int kvm_cpu_get_interrupt(struct kvm_vcpu *v) 66 { 67 struct kvm_pic *s; 68 int vector; 69 70 if (!irqchip_in_kernel(v->kvm)) 71 return v->arch.interrupt.nr; 72 73 vector = kvm_get_apic_interrupt(v); /* APIC */ 74 if (vector == -1) { 75 if (kvm_apic_accept_pic_intr(v)) { 76 s = pic_irqchip(v->kvm); 77 s->output = 0; /* PIC */ 78 vector = kvm_pic_read_irq(v->kvm); 79 } 80 } 81 return vector; 82 } 83 EXPORT_SYMBOL_GPL(kvm_cpu_get_interrupt); 84 85 void kvm_inject_pending_timer_irqs(struct kvm_vcpu *vcpu) 86 { 87 kvm_inject_apic_timer_irqs(vcpu); 88 /* TODO: PIT, RTC etc. */ 89 } 90 EXPORT_SYMBOL_GPL(kvm_inject_pending_timer_irqs); 91 92 void __kvm_migrate_timers(struct kvm_vcpu *vcpu) 93 { 94 __kvm_migrate_apic_timer(vcpu); 95 __kvm_migrate_pit_timer(vcpu); 96 } 97