From d0af7882df9939cad5fffe6b4334e078ef244fca Mon Sep 17 00:00:00 2001 From: Mark McLoughlin Date: Tue, 2 Dec 2008 12:16:33 +0000 Subject: [PATCH] --- yaml --- r: 125301 b: refs/heads/master c: defaf1587c5d7dff828f6f11c8941e5bcef00f50 h: refs/heads/master i: 125299: 35019f186e967ff11ad53d1f57a4fcaa5031efdc v: v3 --- [refs] | 2 +- trunk/include/linux/kvm_host.h | 1 + trunk/virt/kvm/kvm_main.c | 15 ++++++++++++++- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/[refs] b/[refs] index 441c910e0c1b..dc188c378538 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: eb64f1e8cd5c3cae912db30a77d062367f7a11a6 +refs/heads/master: defaf1587c5d7dff828f6f11c8941e5bcef00f50 diff --git a/trunk/include/linux/kvm_host.h b/trunk/include/linux/kvm_host.h index 8091a4d90ddf..eafabd5c66b2 100644 --- a/trunk/include/linux/kvm_host.h +++ b/trunk/include/linux/kvm_host.h @@ -307,6 +307,7 @@ struct kvm_assigned_dev_kernel { int host_busnr; int host_devfn; int host_irq; + bool host_irq_disabled; int guest_irq; struct msi_msg guest_msi; #define KVM_ASSIGNED_DEV_GUEST_INTX (1 << 0) diff --git a/trunk/virt/kvm/kvm_main.c b/trunk/virt/kvm/kvm_main.c index eb70ca6c7145..fc6127cbea1f 100644 --- a/trunk/virt/kvm/kvm_main.c +++ b/trunk/virt/kvm/kvm_main.c @@ -170,6 +170,7 @@ static void kvm_assigned_dev_interrupt_work_handler(struct work_struct *work) KVM_ASSIGNED_DEV_GUEST_MSI) { assigned_device_msi_dispatch(assigned_dev); enable_irq(assigned_dev->host_irq); + assigned_dev->host_irq_disabled = false; } mutex_unlock(&assigned_dev->kvm->lock); kvm_put_kvm(assigned_dev->kvm); @@ -181,8 +182,12 @@ static irqreturn_t kvm_assigned_dev_intr(int irq, void *dev_id) (struct kvm_assigned_dev_kernel *) dev_id; kvm_get_kvm(assigned_dev->kvm); + schedule_work(&assigned_dev->interrupt_work); + disable_irq_nosync(irq); + assigned_dev->host_irq_disabled = true; + return IRQ_HANDLED; } @@ -196,8 +201,16 @@ static void kvm_assigned_dev_ack_irq(struct kvm_irq_ack_notifier *kian) dev = container_of(kian, struct kvm_assigned_dev_kernel, ack_notifier); + kvm_set_irq(dev->kvm, dev->irq_source_id, dev->guest_irq, 0); - enable_irq(dev->host_irq); + + /* The guest irq may be shared so this ack may be + * from another device. + */ + if (dev->host_irq_disabled) { + enable_irq(dev->host_irq); + dev->host_irq_disabled = false; + } } static void kvm_free_assigned_irq(struct kvm *kvm,