aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/lapic.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kvm/lapic.c')
-rw-r--r--arch/x86/kvm/lapic.c34
1 files changed, 29 insertions, 5 deletions
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index 0fc3cab48943..206cc11a1c97 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -380,6 +380,14 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode,
380 } 380 }
381 break; 381 break;
382 382
383 case APIC_DM_EXTINT:
384 /*
385 * Should only be called by kvm_apic_local_deliver() with LVT0,
386 * before NMI watchdog was enabled. Already handled by
387 * kvm_apic_accept_pic_intr().
388 */
389 break;
390
383 default: 391 default:
384 printk(KERN_ERR "TODO: unsupported delivery mode %x\n", 392 printk(KERN_ERR "TODO: unsupported delivery mode %x\n",
385 delivery_mode); 393 delivery_mode);
@@ -743,10 +751,13 @@ static void apic_mmio_write(struct kvm_io_device *this,
743 apic_set_reg(apic, APIC_ICR2, val & 0xff000000); 751 apic_set_reg(apic, APIC_ICR2, val & 0xff000000);
744 break; 752 break;
745 753
754 case APIC_LVT0:
755 if (val == APIC_DM_NMI)
756 apic_debug("Receive NMI setting on APIC_LVT0 "
757 "for cpu %d\n", apic->vcpu->vcpu_id);
746 case APIC_LVTT: 758 case APIC_LVTT:
747 case APIC_LVTTHMR: 759 case APIC_LVTTHMR:
748 case APIC_LVTPC: 760 case APIC_LVTPC:
749 case APIC_LVT0:
750 case APIC_LVT1: 761 case APIC_LVT1:
751 case APIC_LVTERR: 762 case APIC_LVTERR:
752 /* TODO: Check vector */ 763 /* TODO: Check vector */
@@ -961,12 +972,25 @@ int apic_has_pending_timer(struct kvm_vcpu *vcpu)
961 return 0; 972 return 0;
962} 973}
963 974
964static int __inject_apic_timer_irq(struct kvm_lapic *apic) 975int kvm_apic_local_deliver(struct kvm_vcpu *vcpu, int lvt_type)
965{ 976{
966 int vector; 977 struct kvm_lapic *apic = vcpu->arch.apic;
978 int vector, mode, trig_mode;
979 u32 reg;
980
981 if (apic && apic_enabled(apic)) {
982 reg = apic_get_reg(apic, lvt_type);
983 vector = reg & APIC_VECTOR_MASK;
984 mode = reg & APIC_MODE_MASK;
985 trig_mode = reg & APIC_LVT_LEVEL_TRIGGER;
986 return __apic_accept_irq(apic, mode, vector, 1, trig_mode);
987 }
988 return 0;
989}
967 990
968 vector = apic_lvt_vector(apic, APIC_LVTT); 991static inline int __inject_apic_timer_irq(struct kvm_lapic *apic)
969 return __apic_accept_irq(apic, APIC_DM_FIXED, vector, 1, 0); 992{
993 return kvm_apic_local_deliver(apic->vcpu, APIC_LVTT);
970} 994}
971 995
972static enum hrtimer_restart apic_timer_fn(struct hrtimer *data) 996static enum hrtimer_restart apic_timer_fn(struct hrtimer *data)