linux/arch/x86/kvm/irq.c
<<
>>
Prefs
   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 */
  34int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu)
  35{
  36        return apic_has_pending_timer(vcpu);
  37}
  38EXPORT_SYMBOL(kvm_cpu_has_pending_timer);
  39
  40/*
  41 * check if there is pending interrupt from
  42 * non-APIC source without intack.
  43 */
  44static int kvm_cpu_has_extint(struct kvm_vcpu *v)
  45{
  46        if (kvm_apic_accept_pic_intr(v))
  47                return pic_irqchip(v->kvm)->output;     /* PIC */
  48        else
  49                return 0;
  50}
  51
  52/*
  53 * check if there is injectable interrupt:
  54 * when virtual interrupt delivery enabled,
  55 * interrupt from apic will handled by hardware,
  56 * we don't need to check it here.
  57 */
  58int kvm_cpu_has_injectable_intr(struct kvm_vcpu *v)
  59{
  60        if (!irqchip_in_kernel(v->kvm))
  61                return v->arch.interrupt.pending;
  62
  63        if (kvm_cpu_has_extint(v))
  64                return 1;
  65
  66        if (kvm_apic_vid_enabled(v->kvm))
  67                return 0;
  68
  69        return kvm_apic_has_interrupt(v) != -1; /* LAPIC */
  70}
  71
  72/*
  73 * check if there is pending interrupt without
  74 * intack.
  75 */
  76int kvm_cpu_has_interrupt(struct kvm_vcpu *v)
  77{
  78        if (!irqchip_in_kernel(v->kvm))
  79                return v->arch.interrupt.pending;
  80
  81        if (kvm_cpu_has_extint(v))
  82                return 1;
  83
  84        return kvm_apic_has_interrupt(v) != -1; /* LAPIC */
  85}
  86EXPORT_SYMBOL_GPL(kvm_cpu_has_interrupt);
  87
  88/*
  89 * Read pending interrupt(from non-APIC source)
  90 * vector and intack.
  91 */
  92static int kvm_cpu_get_extint(struct kvm_vcpu *v)
  93{
  94        if (kvm_cpu_has_extint(v))
  95                return kvm_pic_read_irq(v->kvm); /* PIC */
  96        return -1;
  97}
  98
  99/*
 100 * Read pending interrupt vector and intack.
 101 */
 102int kvm_cpu_get_interrupt(struct kvm_vcpu *v)
 103{
 104        int vector;
 105
 106        if (!irqchip_in_kernel(v->kvm))
 107                return v->arch.interrupt.nr;
 108
 109        vector = kvm_cpu_get_extint(v);
 110
 111        if (kvm_apic_vid_enabled(v->kvm) || vector != -1)
 112                return vector;                  /* PIC */
 113
 114        return kvm_get_apic_interrupt(v);       /* APIC */
 115}
 116
 117void kvm_inject_pending_timer_irqs(struct kvm_vcpu *vcpu)
 118{
 119        kvm_inject_apic_timer_irqs(vcpu);
 120        /* TODO: PIT, RTC etc. */
 121}
 122EXPORT_SYMBOL_GPL(kvm_inject_pending_timer_irqs);
 123
 124void __kvm_migrate_timers(struct kvm_vcpu *vcpu)
 125{
 126        __kvm_migrate_apic_timer(vcpu);
 127        __kvm_migrate_pit_timer(vcpu);
 128}
 129