aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/i8254.c
diff options
context:
space:
mode:
authorSheng Yang <sheng@linux.intel.com>2008-10-15 08:15:06 -0400
committerAvi Kivity <avi@redhat.com>2008-10-28 08:21:34 -0400
commit5550af4df179e52753d3a43a788a113ad8cd95cd (patch)
treef19274a4f7e345e70e7da713f44c1dcccdb134e8 /arch/x86/kvm/i8254.c
parent6ad9f15c94822c3f067a7d443f3b414e08b34460 (diff)
KVM: Fix guest shared interrupt with in-kernel irqchip
Every call of kvm_set_irq() should offer an irq_source_id, which is allocated by kvm_request_irq_source_id(). Based on irq_source_id, we identify the irq source and implement logical OR for shared level interrupts. The allocated irq_source_id can be freed by kvm_free_irq_source_id(). Currently, we support at most sizeof(unsigned long) different irq sources. [Amit: - rebase to kvm.git HEAD - move definition of KVM_USERSPACE_IRQ_SOURCE_ID to common file - move kvm_request_irq_source_id to the update_irq ioctl] [Xiantao: - Add kvm/ia64 stuff and make it work for kvm/ia64 guests] Signed-off-by: Sheng Yang <sheng@linux.intel.com> Signed-off-by: Amit Shah <amit.shah@redhat.com> Signed-off-by: Xiantao Zhang <xiantao.zhang@intel.com> Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86/kvm/i8254.c')
-rw-r--r--arch/x86/kvm/i8254.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c
index 11c6725fb798..8772dc946823 100644
--- a/arch/x86/kvm/i8254.c
+++ b/arch/x86/kvm/i8254.c
@@ -545,6 +545,12 @@ struct kvm_pit *kvm_create_pit(struct kvm *kvm)
545 if (!pit) 545 if (!pit)
546 return NULL; 546 return NULL;
547 547
548 mutex_lock(&kvm->lock);
549 pit->irq_source_id = kvm_request_irq_source_id(kvm);
550 mutex_unlock(&kvm->lock);
551 if (pit->irq_source_id < 0)
552 return NULL;
553
548 mutex_init(&pit->pit_state.lock); 554 mutex_init(&pit->pit_state.lock);
549 mutex_lock(&pit->pit_state.lock); 555 mutex_lock(&pit->pit_state.lock);
550 spin_lock_init(&pit->pit_state.inject_lock); 556 spin_lock_init(&pit->pit_state.inject_lock);
@@ -587,6 +593,7 @@ void kvm_free_pit(struct kvm *kvm)
587 mutex_lock(&kvm->arch.vpit->pit_state.lock); 593 mutex_lock(&kvm->arch.vpit->pit_state.lock);
588 timer = &kvm->arch.vpit->pit_state.pit_timer.timer; 594 timer = &kvm->arch.vpit->pit_state.pit_timer.timer;
589 hrtimer_cancel(timer); 595 hrtimer_cancel(timer);
596 kvm_free_irq_source_id(kvm, kvm->arch.vpit->irq_source_id);
590 mutex_unlock(&kvm->arch.vpit->pit_state.lock); 597 mutex_unlock(&kvm->arch.vpit->pit_state.lock);
591 kfree(kvm->arch.vpit); 598 kfree(kvm->arch.vpit);
592 } 599 }
@@ -595,8 +602,8 @@ void kvm_free_pit(struct kvm *kvm)
595static void __inject_pit_timer_intr(struct kvm *kvm) 602static void __inject_pit_timer_intr(struct kvm *kvm)
596{ 603{
597 mutex_lock(&kvm->lock); 604 mutex_lock(&kvm->lock);
598 kvm_set_irq(kvm, 0, 1); 605 kvm_set_irq(kvm, kvm->arch.vpit->irq_source_id, 0, 1);
599 kvm_set_irq(kvm, 0, 0); 606 kvm_set_irq(kvm, kvm->arch.vpit->irq_source_id, 0, 0);
600 mutex_unlock(&kvm->lock); 607 mutex_unlock(&kvm->lock);
601} 608}
602 609