From mboxrd@z Thu Jan 1 00:00:00 1970 From: Sheng Yang Subject: [PATCH 1/4] Separate update irq to a single function Date: Wed, 8 Oct 2008 16:38:10 +0800 Message-ID: <1223455093-304-2-git-send-email-sheng@linux.intel.com> References: <1223455093-304-1-git-send-email-sheng@linux.intel.com> Cc: kvm@vger.kernel.org, Sheng Yang To: Avi Kivity Return-path: Received: from mga02.intel.com ([134.134.136.20]:21796 "EHLO mga02.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753479AbYJHIjm (ORCPT ); Wed, 8 Oct 2008 04:39:42 -0400 In-Reply-To: <1223455093-304-1-git-send-email-sheng@linux.intel.com> Sender: kvm-owner@vger.kernel.org List-ID: Signed-off-by: Sheng Yang --- arch/x86/kvm/x86.c | 82 +++++++++++++++++++++++++++++---------------------- 1 files changed, 47 insertions(+), 35 deletions(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 932d03e..57825a1 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -206,6 +206,40 @@ static void kvm_free_all_assigned_devices(struct kvm *kvm) } } +static int assigned_device_update_irq(struct kvm *kvm, + struct kvm_assigned_dev_kernel *assigned_dev, + struct kvm_assigned_irq *assigned_irq) +{ + if (assigned_dev->irq_requested) { + assigned_dev->guest_irq = assigned_irq->guest_irq; + assigned_dev->ack_notifier.gsi = assigned_irq->guest_irq; + return 0; + } + if (irqchip_in_kernel(kvm)) { + if (!capable(CAP_SYS_RAWIO)) + return -EPERM; + + if (assigned_irq->host_irq) + assigned_dev->host_irq = assigned_irq->host_irq; + else + assigned_dev->host_irq = assigned_dev->dev->irq; + assigned_dev->guest_irq = assigned_dev->guest_irq; + assigned_dev->ack_notifier.gsi = assigned_dev->guest_irq; + + /* Even though this is PCI, we don't want to use shared + * interrupts. Sharing host devices with guest-assigned devices + * on the same interrupt line is not a happy situation: there + * are going to be long delays in accepting, acking, etc. + */ + if (request_irq(assigned_dev->host_irq, kvm_assigned_dev_intr, + 0, "kvm_assigned_device", (void *)assigned_dev)) + return -EIO; + } + assigned_dev->irq_requested = true; + + return 0; +} + static int kvm_vm_ioctl_assign_irq(struct kvm *kvm, struct kvm_assigned_irq *assigned_irq) @@ -222,44 +256,22 @@ static int kvm_vm_ioctl_assign_irq(struct kvm *kvm, return -EINVAL; } - if (match->irq_requested) { - match->guest_irq = assigned_irq->guest_irq; - match->ack_notifier.gsi = assigned_irq->guest_irq; - mutex_unlock(&kvm->lock); - return 0; - } - - INIT_WORK(&match->interrupt_work, - kvm_assigned_dev_interrupt_work_handler); - - if (irqchip_in_kernel(kvm)) { - if (!capable(CAP_SYS_RAWIO)) { - r = -EPERM; - goto out_release; - } - - if (assigned_irq->host_irq) - match->host_irq = assigned_irq->host_irq; - else - match->host_irq = match->dev->irq; - match->guest_irq = assigned_irq->guest_irq; - match->ack_notifier.gsi = assigned_irq->guest_irq; - match->ack_notifier.irq_acked = kvm_assigned_dev_ack_irq; - kvm_register_irq_ack_notifier(kvm, &match->ack_notifier); - - /* Even though this is PCI, we don't want to use shared - * interrupts. Sharing host devices with guest-assigned devices - * on the same interrupt line is not a happy situation: there - * are going to be long delays in accepting, acking, etc. - */ - if (request_irq(match->host_irq, kvm_assigned_dev_intr, 0, - "kvm_assigned_device", (void *)match)) { - r = -EIO; - goto out_release; + if (!match->irq_requested) { + INIT_WORK(&match->interrupt_work, + kvm_assigned_dev_interrupt_work_handler); + if (irqchip_in_kernel(kvm)) { + match->ack_notifier.gsi = -1; + match->ack_notifier.irq_acked = + kvm_assigned_dev_ack_irq; + kvm_register_irq_ack_notifier(kvm, + &match->ack_notifier); } } - match->irq_requested = true; + r = assigned_device_update_irq(kvm, match, assigned_irq); + if (r) + goto out_release; + mutex_unlock(&kvm->lock); return r; out_release: -- 1.5.4.5